Skip to content

Commit ca66e29

Browse files
authored
Merge pull request #16946 from marcusmoore/bug/sc-29166
Gracefully handle error when editing of soft deleted users
2 parents 6eb3819 + 9600ade commit ca66e29

File tree

3 files changed

+52
-2
lines changed

3 files changed

+52
-2
lines changed

app/Http/Controllers/Users/UsersController.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ private function filterDisplayable($permissions)
178178
* @author [A. Gianotto] [<[email protected]>]
179179
* @since [v1.0]
180180
* @param $permissions
181-
* @return \Illuminate\Contracts\View\View
181+
* @return \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
182182
* @internal param int $id
183183
* @throws \Illuminate\Auth\Access\AuthorizationException
184184
*/
@@ -190,6 +190,10 @@ public function edit(User $user)
190190

191191
if ($user) {
192192

193+
if ($user->trashed()) {
194+
return redirect()->route('users.show', $user->id);
195+
}
196+
193197
$permissions = config('permissions');
194198
$groups = Group::pluck('name', 'id');
195199

app/Rules/UserCannotSwitchCompaniesIfItemsAssigned.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class UserCannotSwitchCompaniesIfItemsAssigned implements ValidationRule
1515
*/
1616
public function validate(string $attribute, mixed $value, Closure $fail): void
1717
{
18-
$user = User::find(request()->route('user')->id);
18+
$user = request()->route('user');
1919

2020
if (($value) && ($user->allAssignedCount() > 0) && (Setting::getSettings()->full_multiple_companies_support=='1')) {
2121

tests/Feature/Users/Ui/UpdateUserTest.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use App\Models\Asset;
66
use App\Models\Company;
77
use App\Models\User;
8+
use Error;
89
use Tests\TestCase;
910

1011
class UpdateUserTest extends TestCase
@@ -16,6 +17,15 @@ public function testPageRenders()
1617
->assertOk();
1718
}
1819

20+
public function testCannotViewEditPageForSoftDeletedUser()
21+
{
22+
$user = User::factory()->trashed()->create();
23+
24+
$this->actingAs(User::factory()->superuser()->create())
25+
->get(route('users.edit', $user->id))
26+
->assertRedirectToRoute('users.show', $user->id);
27+
}
28+
1929
public function testUsersCanBeActivatedWithNumber()
2030
{
2131
$admin = User::factory()->superuser()->create();
@@ -161,4 +171,40 @@ public function testMultiCompanyUserCanBeUpdatedIfHasAssetInSameCompany()
161171

162172
$this->followRedirects($response)->assertSee('success');
163173
}
174+
175+
/**
176+
* This can occur if the user edit screen is open in one tab and
177+
* the user is deleted in another before the edit form is submitted.
178+
* @link https://app.shortcut.com/grokability/story/29166
179+
*/
180+
public function testAttemptingToUpdateDeletedUserIsHandledGracefully()
181+
{
182+
[$companyA, $companyB] = Company::factory()->count(2)->create();
183+
$user = User::factory()->for($companyA)->create();
184+
Asset::factory()->assignedToUser($user)->create();
185+
186+
$id = $user->id;
187+
188+
$user->delete();
189+
190+
$response = $this->actingAs(User::factory()->editUsers()->create())
191+
->put(route('users.update', $id), [
192+
'first_name' => 'test',
193+
'username' => 'test',
194+
'company_id' => $companyB->id,
195+
]);
196+
197+
$this->assertFalse($response->exceptions->contains(function ($exception) {
198+
// Avoid hard 500
199+
return $exception instanceof Error;
200+
}));
201+
202+
// As of now, the user will be updated but not be restored
203+
$this->assertDatabaseHas('users', [
204+
'id' => $id,
205+
'first_name' => 'test',
206+
'username' => 'test',
207+
'company_id' => $companyB->id,
208+
]);
209+
}
164210
}

0 commit comments

Comments
 (0)