Approach 1:
One way to accomplish this it to create a second class called CrudArticle (or whatever), make it extend the original Article class but then, add a global scope to this model that limits all queries to the table using the class to only include records that belong to the current user. Use this class with your CRUD panel and the normal Articles class elsewhere in your application.
class CrudArticle extends Article {
public static function boot()
{
parent::boot();
// only include models that belong to this user
$user_id = 0;
Auth::check();
if ($user = Auth::user()) {
$user_id = $user->id;
}
static::addGlobalScope('userFilter', static function (Builder $builder) use ($user_id){
$builder->where('user_id', $user_id);
});
}
}
NOTE: This will prevent the non-owned records from appearing on the list page and prevent loading of the edit page via a direct url. However, Im not 100% sure the above alone would protect from inserts (post requests directly to the update endpoint), ie, you might still need the change for the "UpdateRequest" recomended in the second possible solution below
Approach 2:
Another way to accomplish this is to modify the queries used by the CRUD for example, in your CRUD controller:
/**
* Set up the "list" or "read" operation for the resource
*/
public function setupListOperation(): void
{
// ... normal setup code ...
Auth::check();
$user = Auth::user();
if (!$user) {
throw new \Exception('Unauthorized');
}
$this->crud->query = $this->crud->query->where('user_id', $user->id);
}
To prevent viewing of the update page via a direct url, you can add something like this to setupUpdateOperation:
/**
* Set up the "update" operation for the resource
*/
public function setupUpdateOperation(): void
{
// ... normal setup code ...
$authorized = false;
// only allow viewing the update page if the user is logged in and owns the Article
Auth::check();
if ($user = Auth::user()) {
$id = $this->get('id');
$product = Article::find($id);
if ($product) {
$authorized = $product->user_id === $user->id;
}
}
if (!$authorized) {
$this->crud->denyAccess(['update']);
}
}
To prevent unauthorized edits posted directly to the update endpoint, you'll need to also add something like the below to your UpdateRequest:
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
$authorized = false;
// only allow updates if the user is logged in and owns the Article
Auth::check();
if ($user = Auth::user()) {
$id = $this->get('id');
$product = Article::find($id);
if ($product) {
$authorized = $product->user_id === $user->id;
}
}
return $authorized;
}
Alternatively, you could add a global scope to the model in question as explained here though I tend to avoid that as it changes behavior across the whole app