Handle deletion better

This commit is contained in:
Lance Pioch 2024-03-18 21:23:13 -04:00
parent 2aa9be62a1
commit c4a471f91a
6 changed files with 27 additions and 70 deletions

View File

@ -5,7 +5,6 @@ namespace App\Console\Commands\User;
use App\Models\User; use App\Models\User;
use Webmozart\Assert\Assert; use Webmozart\Assert\Assert;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use App\Services\Users\UserDeletionService;
class DeleteUserCommand extends Command class DeleteUserCommand extends Command
{ {
@ -13,14 +12,6 @@ class DeleteUserCommand extends Command
protected $signature = 'p:user:delete {--user=}'; protected $signature = 'p:user:delete {--user=}';
/**
* DeleteUserCommand constructor.
*/
public function __construct(private UserDeletionService $deletionService)
{
parent::__construct();
}
public function handle(): int public function handle(): int
{ {
$search = $this->option('user') ?? $this->ask(trans('command/messages.user.search_users')); $search = $this->option('user') ?? $this->ask(trans('command/messages.user.search_users'));
@ -62,7 +53,9 @@ class DeleteUserCommand extends Command
} }
if ($this->confirm(trans('command/messages.user.confirm_delete')) || !$this->input->isInteractive()) { if ($this->confirm(trans('command/messages.user.confirm_delete')) || !$this->input->isInteractive()) {
$this->deletionService->handle($deleteUser); $user = User::query()->findOrFail($deleteUser);
$user->delete();
$this->info(trans('command/messages.user.deleted')); $this->info(trans('command/messages.user.deleted'));
} }

View File

@ -10,13 +10,11 @@ use Illuminate\Http\RedirectResponse;
use Prologue\Alerts\AlertsMessageBag; use Prologue\Alerts\AlertsMessageBag;
use Spatie\QueryBuilder\QueryBuilder; use Spatie\QueryBuilder\QueryBuilder;
use Illuminate\View\Factory as ViewFactory; use Illuminate\View\Factory as ViewFactory;
use App\Exceptions\DisplayException;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Illuminate\Contracts\Translation\Translator; use Illuminate\Contracts\Translation\Translator;
use App\Services\Users\UserUpdateService; use App\Services\Users\UserUpdateService;
use App\Traits\Helpers\AvailableLanguages; use App\Traits\Helpers\AvailableLanguages;
use App\Services\Users\UserCreationService; use App\Services\Users\UserCreationService;
use App\Services\Users\UserDeletionService;
use App\Http\Requests\Admin\UserFormRequest; use App\Http\Requests\Admin\UserFormRequest;
use App\Http\Requests\Admin\NewUserFormRequest; use App\Http\Requests\Admin\NewUserFormRequest;
@ -30,7 +28,6 @@ class UserController extends Controller
public function __construct( public function __construct(
protected AlertsMessageBag $alert, protected AlertsMessageBag $alert,
protected UserCreationService $creationService, protected UserCreationService $creationService,
protected UserDeletionService $deletionService,
protected Translator $translator, protected Translator $translator,
protected UserUpdateService $updateService, protected UserUpdateService $updateService,
protected ViewFactory $view protected ViewFactory $view
@ -84,13 +81,9 @@ class UserController extends Controller
* @throws \Exception * @throws \Exception
* @throws \App\Exceptions\DisplayException * @throws \App\Exceptions\DisplayException
*/ */
public function delete(Request $request, User $user): RedirectResponse public function delete(User $user): RedirectResponse
{ {
if ($request->user()->id === $user->id) { $user->delete();
throw new DisplayException($this->translator->get('admin/user.exceptions.user_has_servers'));
}
$this->deletionService->handle($user);
return redirect()->route('admin.users'); return redirect()->route('admin.users');
} }
@ -130,19 +123,20 @@ class UserController extends Controller
*/ */
public function json(Request $request): JsonResponse public function json(Request $request): JsonResponse
{ {
$userPaginator = QueryBuilder::for(User::query())->allowedFilters(['email'])->paginate(25); // Handle single user requests | TODO: Separate this out into its own method
if ($userId = $request->query('user_id')) {
/** @var User[] $users */ $user = User::query()->findOrFail($userId);
$users = $userPaginator->items();
// Handle single user requests.
if ($request->query('user_id')) {
$user = User::query()->findOrFail($request->input('user_id'));
$user['md5'] = md5(strtolower($user->email)); $user['md5'] = md5(strtolower($user->email));
return response()->json($user); return response()->json($user);
} }
// Handle all users list
$userPaginator = QueryBuilder::for(User::query())->allowedFilters(['email'])->paginate(25);
/** @var User[] $users */
$users = $userPaginator->items();
return response()->json(collect($users)->map(function (User $user) { return response()->json(collect($users)->map(function (User $user) {
$user['md5'] = md5(strtolower($user->email)); $user['md5'] = md5(strtolower($user->email));

View File

@ -7,7 +7,6 @@ use Illuminate\Http\JsonResponse;
use Spatie\QueryBuilder\QueryBuilder; use Spatie\QueryBuilder\QueryBuilder;
use App\Services\Users\UserUpdateService; use App\Services\Users\UserUpdateService;
use App\Services\Users\UserCreationService; use App\Services\Users\UserCreationService;
use App\Services\Users\UserDeletionService;
use App\Transformers\Api\Application\UserTransformer; use App\Transformers\Api\Application\UserTransformer;
use App\Http\Requests\Api\Application\Users\GetUsersRequest; use App\Http\Requests\Api\Application\Users\GetUsersRequest;
use App\Http\Requests\Api\Application\Users\StoreUserRequest; use App\Http\Requests\Api\Application\Users\StoreUserRequest;
@ -22,7 +21,6 @@ class UserController extends ApplicationApiController
*/ */
public function __construct( public function __construct(
private UserCreationService $creationService, private UserCreationService $creationService,
private UserDeletionService $deletionService,
private UserUpdateService $updateService private UserUpdateService $updateService
) { ) {
parent::__construct(); parent::__construct();
@ -99,14 +97,11 @@ class UserController extends ApplicationApiController
} }
/** /**
* Handle a request to delete a user from the Panel. Returns a HTTP/204 response * Handle a request to delete a user from the Panel. Returns a HTTP/204 response on successful deletion.
* on successful deletion.
*
* @throws \App\Exceptions\DisplayException
*/ */
public function delete(DeleteUserRequest $request, User $user): JsonResponse public function delete(DeleteUserRequest $request, User $user): JsonResponse
{ {
$this->deletionService->handle($user); $user->delete();
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT); return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
} }

View File

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use App\Exceptions\DisplayException;
use App\Rules\Username; use App\Rules\Username;
use App\Facades\Activity; use App\Facades\Activity;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@ -167,6 +168,15 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac
'totp_secret' => 'nullable|string', 'totp_secret' => 'nullable|string',
]; ];
protected static function booted(): void
{
static::deleting(function (self $user) {
throw_if($user->servers()->count() > 0, new DisplayException(__('admin/user.exceptions.user_has_servers')));
throw_if(request()->user()?->id === $user->id, new DisplayException(__('admin/user.exceptions.user_is_self')));
});
}
/** /**
* Implement language verification by overriding Eloquence's gather * Implement language verification by overriding Eloquence's gather
* rules function. * rules function.

View File

@ -1,36 +0,0 @@
<?php
namespace App\Services\Users;
use App\Models\User;
use App\Exceptions\DisplayException;
use Illuminate\Contracts\Translation\Translator;
class UserDeletionService
{
/**
* UserDeletionService constructor.
*/
public function __construct(
protected Translator $translator
) {
}
/**
* Delete a user from the panel only if they have no servers attached to their account.
*
* @throws DisplayException
*/
public function handle(int|User $user): ?bool
{
if (is_int($user)) {
$user = User::findOrFail($user);
}
if ($user->servers()->count() > 0) {
throw new DisplayException($this->translator->get('admin/user.exceptions.user_has_servers'));
}
return $user->delete();
}
}

View File

@ -3,6 +3,7 @@
return [ return [
'exceptions' => [ 'exceptions' => [
'user_has_servers' => 'Cannot delete a user with active servers attached to their account. Please delete their servers before continuing.', 'user_has_servers' => 'Cannot delete a user with active servers attached to their account. Please delete their servers before continuing.',
'user_is_self' => 'Cannot delete your own user account.',
], ],
'notices' => [ 'notices' => [
'account_created' => 'Account has been created successfully.', 'account_created' => 'Account has been created successfully.',