feat: Autorização implementada em todos os controladores.

This commit is contained in:
lukibeg 2025-11-27 20:35:44 -03:00
parent 578e26f5da
commit cc52c73f69
9 changed files with 68 additions and 31 deletions

View File

@ -18,9 +18,11 @@ class AddClient extends Component
public function save(ClientService $clientService)
{
$this->form->validate();
try {
$this->authorize('addClient', Auth::user());
$this->form->validate();
$data = $this->form->all();
$data['name'] = $data['client_name'];
@ -36,7 +38,7 @@ public function save(ClientService $clientService)
$this->dispatch('client-added');
$this->dispatch('notify', message: $client->name . ' adicionado com sucesso!');
} catch (\Exception $e) {
$this->dispatch('notify', message: 'Ocorreu um erro inesperado ao salvar.', type: 'error');
$this->dispatch('notify', message: 'Ocorreu um erro inesperado ao salvar. ' . $e->getMessage(), type: 'error');
}
}

View File

@ -5,25 +5,36 @@
use Livewire\Component;
use Livewire\Attributes\On;
use App\Models\Client;
use Exception;
use Illuminate\Support\Facades\Auth;
class DeleteClient extends Component
{
#[On('confirm-delete')]
public function deleteClient($payload)
{
try {
// Sua lógica de autorização e exclusão (Correta)
$this->authorize('deleteClient', Auth::user());
$deletedClient = Client::findOrFail($payload);
$deletedClient = Client::findOrFail($payload);
if ($deletedClient) {
$deletedClient->delete();
if ($deletedClient) {
$deletedClient->delete();
}
// Sucesso (Dentro do try, onde deve estar)
$this->dispatch('client-deleted');
$this->dispatch('notify', message: 'Cliente excluído com sucesso!');
} catch (Exception $e) {
// Tratamento de erro
$this->dispatch('notify', message: 'Você não possui permissão para realizar essa ação.', type: 'error');
}
$this->dispatch('client-deleted');
$this->dispatch('notify', message: 'Cliente excluído com sucesso!');
}
public function render()
{
return '<div></div>';
}
}
}

View File

@ -5,6 +5,7 @@
use App\Livewire\Forms\ClientForm;
use App\Models\Client;
use App\Services\ClientService;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;
use Livewire\Attributes\On;
use Livewire\Component;
@ -18,7 +19,6 @@ class EditClient extends Component
public Client $client;
public ClientForm $clientForm;
// public ClientService $clientService;
#[On('update-client')]
public function loadClient($id)
@ -35,17 +35,19 @@ public function loadClient($id)
}
public function edit(ClientService $clientService)
{
$data = $this->clientForm->validate();
if ($this->clientForm->profile_image_path) {
$path = $this->clientForm->profile_image_path->store('client_logos', 'public');
$data['profile_image_path'] = $path;
}
$data['root_password'] = Crypt::encryptString($data['root_password']);
try {
$this->authorize('editClient', Auth::user());
$data = $this->clientForm->validate();
if ($this->clientForm->profile_image_path) {
$path = $this->clientForm->profile_image_path->store('client_logos', 'public');
$data['profile_image_path'] = $path;
}
$data['root_password'] = Crypt::encryptString($data['root_password']);
if (!$clientService->updateClient($this->client, $data)) {
throw new Exception('O serviço não confirmou a atualização.');
}

View File

@ -34,11 +34,10 @@ class CreateUser extends Component
public function createUser(UserService $userService)
{
$validated = $this->validate($this->rules, $this->messages);
try {
$this->authorize('createUser', Auth::user());
$validated = $this->validate($this->rules, $this->messages);
$user = $userService->createUser($validated);
@ -49,6 +48,7 @@ public function createUser(UserService $userService)
$this->dispatch('notify', message: 'Usuário cadastrado com sucesso!');
} catch (\Exception $e) {
$this->addError('general', $e->getMessage());
$this->dispatch('notify', message: 'Ocorreu um erro ao criar o usuário. ' . $e->getMessage(), type: 'error');
}
}

View File

@ -6,6 +6,7 @@
use Livewire\Attributes\On;
use App\Models\User;
use App\Services\UserService;
use Illuminate\Support\Facades\Auth;
use Exception;
class DeleteUser extends Component
@ -14,9 +15,11 @@ class DeleteUser extends Component
#[On('confirm-delete-user')]
public function deleteUser(UserService $userService, $payload)
{
$deletedUser = User::findOrFail($payload);
try {
$this->authorize('deleteUser', Auth::user());
$deletedUser = User::findOrFail($payload);
if ($deletedUser) {
$deletedUser = $userService->deleteUser($deletedUser);
}
@ -25,7 +28,7 @@ public function deleteUser(UserService $userService, $payload)
$this->dispatch('notify', message: $deletedUser->name . ' Usuário excluído com sucesso!');
} catch (Exception $e) {
$this->dispatch('user-delete-error');
$this->dispatch('notify', message: $e->getMessage());
$this->dispatch('notify', message: $e->getMessage(), type: 'error');
}
}

View File

@ -7,6 +7,7 @@
use Livewire\Component;
use Livewire\Attributes\On;
use App\Services\UserService;
use Illuminate\Support\Facades\Auth;
class EditUser extends Component
{
@ -31,8 +32,11 @@ public function loadUser($id)
}
public function editUser(UserService $userService)
{
$data = $this->userForm->validate();
try {
$this->authorize('editUser', Auth::user());
$data = $this->userForm->validate();
if (!$userService->updateUser($this->user, $data)) {
throw new \Exception('O serviço não confirmou a atualização.');
}

View File

@ -22,8 +22,21 @@ public function register(): void
*/
public function boot(): void
{
Gate::define('createUser', function (User $user) {
return isset($user->permissions) ? in_array('admin', $user->permissions) : false;
});
// Lista de todas as ações que são exclusivas de Admin
$adminActions = [
'createUser',
'editUser',
'deleteUser',
'addClient', // Exemplo
'deleteClient', // Exemplo
'editClient',
];
foreach ($adminActions as $action) {
Gate::define($action, function (User $user) {
// A lógica fica centralizada aqui. Se mudar, muda pra todos.
return isset($user->permissions) && in_array('admin', $user->permissions);
});
}
}
}

View File

@ -13,6 +13,8 @@ class UserService
public function __construct(protected User $user) {}
public function createUser(array $user)
{
$permissions = [$user['permissions']];
$user['permissions'] = $permissions;
return User::create($user);
}

View File

@ -12,7 +12,7 @@
}
}" @notify.window="addToast($event.detail.message, $event.detail.type || 'success')"
@notifyError.window="addToast($event.detail.message, $event.detail.type || 'error')"
class="fixed top-5 right-5 z-50 flex w-full max-w-xs flex-col space-y-3">
class="fixed top-5 right-5 z-50000 flex w-full max-w-xs flex-col space-y-3">
<template x-for="toast in toasts" :key="toast.id">
<div x-show="true" x-transition:enter="transform ease-out duration-300 transition"
x-transition:enter-start="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
@ -35,7 +35,7 @@ class="fixed top-5 right-5 z-50 flex w-full max-w-xs flex-col space-y-3">
<p class="toast-message" x-text="toast.message"></p>
<button @click="removeToast(toast.id)" class="toast-close-button">
<button @click="removeToast(toast.id)" class="toast-close-button cursor-pointer">
<svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
<path
d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" />