test-policy mit mkro zum Filtern von Datensätzen in Tabelle
This commit is contained in:
@@ -13,6 +13,7 @@ class ContractsTable
|
|||||||
public static function configure(Table $table): Table
|
public static function configure(Table $table): Table
|
||||||
{
|
{
|
||||||
return $table
|
return $table
|
||||||
|
->applyRowAccessPolicy()
|
||||||
->columns([
|
->columns([
|
||||||
TextColumn::make('name')
|
TextColumn::make('name')
|
||||||
->searchable(),
|
->searchable(),
|
||||||
|
|||||||
@@ -3,10 +3,13 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\HasDocuments;
|
use App\HasDocuments;
|
||||||
|
use App\Policies\ContractPolicy;
|
||||||
|
use Illuminate\Database\Eloquent\Attributes\UsePolicy;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||||
|
|
||||||
|
#[UsePolicy(ContractPolicy::class)]
|
||||||
class Contract extends Model
|
class Contract extends Model
|
||||||
{
|
{
|
||||||
use HasDocuments;
|
use HasDocuments;
|
||||||
|
|||||||
74
app/Policies/ContractPolicy.php
Normal file
74
app/Policies/ContractPolicy.php
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Policies;
|
||||||
|
|
||||||
|
use App\Models\Contract;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Auth\Access\Response;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
|
class ContractPolicy
|
||||||
|
{
|
||||||
|
// ContractPolicy.php
|
||||||
|
public function applyRowAccessPolicy(User $user, Builder $query): Builder
|
||||||
|
{
|
||||||
|
// Users can only see their own posts unless they're admins
|
||||||
|
return $query->where('responsible_id', $user->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view any models.
|
||||||
|
*/
|
||||||
|
public function viewAny(User $user): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can view the model.
|
||||||
|
*/
|
||||||
|
public function view(User $user, Contract $contract): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can create models.
|
||||||
|
*/
|
||||||
|
public function create(User $user): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can update the model.
|
||||||
|
*/
|
||||||
|
public function update(User $user, Contract $contract): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can delete the model.
|
||||||
|
*/
|
||||||
|
public function delete(User $user, Contract $contract): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can restore the model.
|
||||||
|
*/
|
||||||
|
public function restore(User $user, Contract $contract): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the user can permanently delete the model.
|
||||||
|
*/
|
||||||
|
public function forceDelete(User $user, Contract $contract): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Filament\Tables\Table;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
class AppServiceProvider extends ServiceProvider
|
class AppServiceProvider extends ServiceProvider
|
||||||
@@ -19,6 +20,58 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
*/
|
*/
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
//
|
# Makro, um die Zeilen zu filtern.
|
||||||
|
# geklaut hier: https://filamentglow.com/trick/implementing-row-level-security-in-filament-tables-with-applyrowaccesspolicy-30090998
|
||||||
|
Table::macro('applyRowAccessPolicy', function (\Closure | bool $condition = true): Table {
|
||||||
|
if ($condition instanceof \Closure) {
|
||||||
|
$condition = $this->evaluate($condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the view row scope condition in Laravel's service container.
|
||||||
|
*
|
||||||
|
* How this works:
|
||||||
|
* 1. We generate a unique ID for each Table instance using spl_object_hash()
|
||||||
|
* 2. We create a container binding with a key specific to this Table instance
|
||||||
|
* 3. The condition value (true/false) is stored in the container
|
||||||
|
*
|
||||||
|
* The container binding will be automatically cleaned up when the Table instance
|
||||||
|
* is garbage collected, as the binding key is unique to this instance.
|
||||||
|
*/
|
||||||
|
$tableId = spl_object_hash($this);
|
||||||
|
app()->instance('filament.table.viewRowScope.' . $tableId, $condition);
|
||||||
|
|
||||||
|
return $this->modifyQueryUsing(function (\Illuminate\Database\Eloquent\Builder $query) use ($tableId): \Illuminate\Database\Eloquent\Builder {
|
||||||
|
// Check the container for this Table's specific viewRowScope setting
|
||||||
|
// Defaults to true if no binding exists (fallback for safety)
|
||||||
|
$shouldApply = app()->bound('filament.table.viewRowScope.' . $tableId)
|
||||||
|
? app()->make('filament.table.viewRowScope.' . $tableId)
|
||||||
|
: true;
|
||||||
|
|
||||||
|
if (! $shouldApply) {
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
$model = $query->getModel();
|
||||||
|
|
||||||
|
if (! $model) {
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
$policy = \Gate::getPolicyFor($model);
|
||||||
|
|
||||||
|
if (! $policy || ! method_exists($policy, 'applyRowAccessPolicy')) {
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
$modifiedQuery = $policy->applyRowAccessPolicy(auth()->user(), $query);
|
||||||
|
|
||||||
|
if (! $modifiedQuery instanceof \Illuminate\Database\Eloquent\Builder) {
|
||||||
|
throw new \RuntimeException("The applyRowAccessPolicy method for " . $policy::class . " must return an instance of Illuminate\Database\Eloquent\Builder.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $modifiedQuery;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user