Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 2 additions & 20 deletions ProcessMaker/Models/ProcessRequestToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Notification;
use Laravel\Scout\Searchable;
use Log;
Expand Down Expand Up @@ -496,25 +497,6 @@ public function getAdvanceStatusAttribute()
return $result;
}

/**
* Check if the user has access to reassign this task
*
* @param User $user
*/
public function authorizeReassignment(User $user)
{
if ($user->can('update', $this)) {
$definitions = $this->getDefinition();
if (empty($definitions['allowReassignment']) || $definitions['allowReassignment'] === 'false') {
throw new AuthorizationException('Not authorized to reassign this task');
}

return true;
} else {
throw new AuthorizationException('Not authorized to view this task');
}
}

/**
* Check if this task can be escalated to the manager by the assignee
*
Expand Down Expand Up @@ -1168,7 +1150,7 @@ public function reassign($toUserId, User $requestingUser)
$reassingAction = true;
} else {
// Validate if user can reassign
$this->authorizeReassignment($requestingUser);
Gate::forUser($requestingUser)->authorize('reassign', $this);
// Reassign user
$this->reassignTo($toUserId);
$this->persistUserData($toUserId);
Expand Down
35 changes: 25 additions & 10 deletions ProcessMaker/Policies/ProcessRequestTokenPolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace ProcessMaker\Policies;

use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Request;
use ProcessMaker\Models\AnonymousUser;
use ProcessMaker\Models\ProcessRequestToken;
Expand All @@ -17,7 +18,7 @@ class ProcessRequestTokenPolicy
* Run before all methods to determine if the
* user is an admin and can do everything.
*
* @param \ProcessMaker\Models\User $user
* @param User $user
* @return mixed
*/
public function before(User $user)
Expand All @@ -30,8 +31,8 @@ public function before(User $user)
/**
* Determine whether the user can view the process request token.
*
* @param \ProcessMaker\Models\User $user
* @param \ProcessMaker\Models\ProcessRequestToken $processRequestToken
* @param User $user
* @param ProcessRequestToken $processRequestToken
* @return mixed
*/
public function view(User $user, ProcessRequestToken $processRequestToken)
Expand All @@ -49,8 +50,8 @@ public function view(User $user, ProcessRequestToken $processRequestToken)
/**
* Determine whether the user can update the process request token.
*
* @param \ProcessMaker\Models\User $user
* @param \ProcessMaker\Models\ProcessRequestToken $processRequestToken
* @param User $user
* @param ProcessRequestToken $processRequestToken
* @return mixed
*/
public function update(User $user, ProcessRequestToken $processRequestToken)
Expand All @@ -70,9 +71,9 @@ public function update(User $user, ProcessRequestToken $processRequestToken)
/**
* Determine if the user can view a screen associated with the task
*
* @param \ProcessMaker\Models\User $user
* @param \ProcessMaker\Models\ProcessRequestToken $processRequestToken
* @param \ProcessMaker\Models\Screen $screen
* @param User $user
* @param ProcessRequestToken $processRequestToken
* @param Screen $screen
* @return mixed
*/
public function viewScreen(User $user, ProcessRequestToken $task, Screen $screen)
Expand All @@ -92,8 +93,8 @@ public function viewScreen(User $user, ProcessRequestToken $task, Screen $screen
/**
* Determine if a user can rollback the process request.
*
* @param \ProcessMaker\Models\User $user
* @param \ProcessMaker\Models\ProcessRequestToken $processRequestToken
* @param User $user
* @param ProcessRequestToken $processRequestToken
*
* @return bool
*/
Expand All @@ -102,4 +103,18 @@ public function rollback(User $user, ProcessRequestToken $task)
// For now, only the process manager can rollback the request
return $user->id === $task->process->managerId;
}

public function reassign(User $user, ProcessRequestToken $task)
{
if ($user->can('update', $task)) {
$definitions = $task->getDefinition();
if (empty($definitions['allowReassignment']) || $definitions['allowReassignment'] === 'false') {
return Response::deny('Not authorized to reassign this task');
}

return true;
} else {
return Response::deny('Not authorized to update this task');
}
}
}
4 changes: 2 additions & 2 deletions database/factories/ProcessMaker/Models/UserFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ public function definition(): array
}

return [
'username' => $this->faker->unique()->userName().'.'.$this->faker->word(),
'username' => $this->faker->unique()->userName() . '.' . $this->faker->word(),
'email' => $this->faker->unique()->email(),
'password' => $GLOBALS['testPassword'],
'status' => $this->faker->randomElement(['ACTIVE', 'INACTIVE']),
'status' => 'ACTIVE',
'firstname' => $this->faker->firstName(),
'lastname' => $this->faker->lastName(),
'address' => $this->faker->streetAddress(),
Expand Down
70 changes: 70 additions & 0 deletions tests/Feature/Api/ProcessRequestTokenPolicyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
use Faker\Factory as Faker;
use Illuminate\Support\Facades\Hash;
use ProcessMaker\Models\Process;
use ProcessMaker\Models\ProcessCategory;
use ProcessMaker\Models\ProcessRequest;
use ProcessMaker\Models\ProcessRequestToken;
use ProcessMaker\Models\ProcessTaskAssignment;
use ProcessMaker\Models\Screen;
Expand Down Expand Up @@ -124,4 +126,72 @@ public function testGetInterstitialNestedScreen()
$response->assertStatus(200);
$this->assertEquals('Screen Interstitial', $response->json()['config'][0]['name']);
}

public function createTaskHelper($allowReassignment, $assignedTo)
{
ProcessCategory::factory()->create(['is_system' => true]);
$this->seed(\ProcessMaker\Package\AdvancedUserManager\Database\Seeds\AssignmentProcessSeeder::class);

$bpmn = file_get_contents(base_path('tests/Feature/Api/bpmnPatterns/SimpleTaskProcess.bpmn'));
$value = $allowReassignment ? 'true' : 'false';
$bpmn = str_replace('pm:allowReassignment="false"', 'pm:allowReassignment="' . $value . '"', $bpmn);
$process = Process::factory()->create(['bpmn' => $bpmn]);

$url = route('api.process_events.trigger', [$process->id, 'event' => 'node_1']);
$this->apiCall('POST', $url);

$task = ProcessRequestToken::where('status', 'ACTIVE')->first();
$task->user_id = $assignedTo->id;
$task->save();

return $task;
}

public function testReassignTask()
{
$assignedUser = User::factory()->create();
$reassignToUser = User::factory()->create();
$task = $this->createTaskHelper(true, $assignedUser);

$this->user = $assignedUser;
$response = $this->apiCall('PUT', route('api.tasks.update', $task), [
'user_id' => $reassignToUser->id,
]);
$response->assertStatus(200);

$this->assertEquals($reassignToUser->id, $task->refresh()->user_id);
}

public function testReassignWithoutTaskSetting()
{
$assignedUser = User::factory()->create();
$reassignToUser = User::factory()->create();
$task = $this->createTaskHelper(false, $assignedUser);

$this->user = $assignedUser;
$response = $this->apiCall('PUT', route('api.tasks.update', $task), [
'user_id' => $reassignToUser->id,
]);
$response->assertStatus(403);

$this->assertEquals('Not authorized to reassign this task', $response->json()['message']);
}

public function testAdminReassignWithoutTaskSetting()
{
$assignedUser = User::factory()->create();
$reassignToUser = User::factory()->create();
$adminUser = User::factory()->create([
'is_administrator' => true,
]);
$task = $this->createTaskHelper(false, $assignedUser);

$this->user = $adminUser;
$response = $this->apiCall('PUT', route('api.tasks.update', $task), [
'user_id' => $reassignToUser->id,
]);
$response->assertStatus(200);

$this->assertEquals($reassignToUser->id, $task->refresh()->user_id);
}
}