# Permisos
Zeus Backoffice incorpora un sistema de permisos basado en las Policies de Laravel.
# Visión general
Un archivo Policy va relacionado con una sección a través de su nombre.
Por ejemplo, una sección cuya clase sea Posts.php
tendrá asociada su Policy PostsPolicy.php
.
Al igual que las secciones residen en la carpeta Sections
, sus policies asociadas residen en la carpeta Policies
.
En un archivo Policy se puede especificar si se permite o no realizar acciones como mostrar una sección, crear, actualizar, eliminar, realizar acciones personalizadas y mostrar elementos y campos.
# Crear Policy
Las Policies se pueden crear fácilmente mediante un comando.
El nombre que hay que especificar al crearla corresponde con el nombre de la sección asociada:
php artisan backoffice:Policy NombreSeccion
Con esto se creará un archivo en la carpeta Policies
junto a la carpeta Sections
, con los métodos index
, create
, update
y delete
retornando true
:
namespace App\Backoffice\Policies;
use App\Models\User;
class PostsPolicy
{
public function index(User $user): bool
{
return true;
}
public function create(User $user): bool
{
return false;
}
public function update(User $user): bool
{
return true;
}
public function delete(User $user): bool
{
return true;
}
}
# Métodos genéricos
index
Sirve para restringir el acceso al listado de datos.
Esto también hará que se muestre o no la sección en la Sidebar.
create
Restringe el visualizar la vista de creación, el crear un registro nuevo y el mostrar el botón de acción CreateAction
.
update
Restringe el visualizar la vista de edición, el actualizar un registro y mostrar el botón de acción de item EditItemAction
.
delete
Restringe el eliminar un registro y mostrar el botón de acción de item DeleteItemAction
.
# Recibir registro actual
Los métodos update
, create
y delete
pueden recibir el registro actual como segundo parámetro para realizar comprobaciones sobre el propio item.
Por ejemplo, si queremos restringir la actualización de un registro sólo si el usuario logueado es el propietario del registro:
public function update(User $user, Post $post)
{
return $post->user_id == $user->id;
}
# Métodos custom
Los métodos custom sirven para restringir acciones como CustomAction
, CustomItemAction
, restringir la visualización de elementos como DataTable
, DataForm
o Card
y campos en un formulario.
Se basan en el uso de la función can
que puede ser usadas en dichos elementos.
Por ejemplo, si tenemos un botón de acción custom y queremos aplicarle una regla de permiso llamada export
:
// app/Backoffice/Sections/Users.php
protected function actions(): array
{
return [
CustomAction::make('Exportar', function () {
// Código para exportar
})->can('export')
];
}
En su archivo de policies tendremos que crear una función llamada export
:
// app/Backoffice/Policies/UsersPolicy.php
class UsersPolicy
{
...
public function export(User $user): bool
{
return $user->can_export == 1;
}
}
# Aplicar a acciones de item custom
En un DataTable, puedes aplicar condiciones a los botones de acción custom de cada item.
Al estar relacionado con un item, junto con el usuario se recibirá también el item:
protected function itemActions(): array
{
return [
EditItemAction::make(),
DeleteItemAction::make(),
CustomItemAction::make('Exportar')
->execute(function (Model $item) {
// Código para exportar
})
->can('exportItem')
];
}
class PostsPolicy
{
...
public function exportItem(User $user, Post $post): bool
{
return $post->user_id == $post->id;
}
}
EditItemAction y DeleteItemAction
Por defecto, al botón de acción EditItemAction
se aplica la condición update
y al DeleteItemAction
la condición delete
.
Ambas reciben junto con el usuario el registro actual.
# Aplicar a campos
Los campos y sus elementos agrupadores como GroupFields
y StackFields
también son susceptibles de recibir una policy mediante la función can
:
protected function fields(): array
{
return [
GroupFields::make('Datos generales', [
TextField::make('Nombre', 'name')->required(),
EmailField::make('Email', 'email')->required()->can('changeEmail')
]),
StackFields::make('Datos de pago', [
TextField::make('Tarjeta', 'card_number'),
TextField::make('Caducidad', 'expire_in'),
])->can('billingData'),
ImageField::make('Avatar', 'avatar')
];
}
# Aplicar a elementos
Los elementos como DataTable
, DataForm
y Card
puede recibir una policy para que se muestren o no:
protected function extraElements(): array
{
return [
DataTable::make('Listado de paises', [
TextField::make('Nombre', 'name'),
TextField::make('ISO Code', 'iso_code')
])
->fromQuery(Country::query())
->can('showCountries')
];
}
# Múltiples condiciones
La función can
puede recibir un string o un array para establecer múltiples condiciones:
CustomAction::make('Exportar', function () {
// Código para exportar
})->can(['exportPDF', 'exportExcel'])
class UsersPolicy
{
...
public function exportPDF(User $user): bool
{
return in_array('pdf', $user->can_export_in);
}
public function exportExcel(User $user): bool
{
return in_array('excel', $user->can_export_in);
}
}