Laravel

Policies

Documentation ⇒ https://laravel.com/docs/5.8/authorization#creating-policies

Au niveau des autorisations, nous avons déjà un système qui nous permet de faire la différence entre une personne connectée, un admin et un invité (personne non connectée).

Maintenant, dans les personnes connectées, il faut être capable de mettre en place un système qui permet d'autoriser une personne à modifier un contenu et pas celui de quelqu'un d'autre.

Dans le cadre du Blogue, l'utilisateur peut modifier ou supprimer ses articles mais pas les articles des autres utilisateurs.

Création de la Class Policies pour le model Post ====

php artisan make:policy PostPolicy --model=Post

Cette commande crée un fichier ⇒ /app/Policies/PostPolicy.php

Dans ce fichier, on retrouve les méthodes par défaut view, create, update, delete, restore, forceDelete

On peut supprimer ou ajouter des méthodes suivant nos besoins.

Pour notre exemple, on va mettre en place la stratégie pour la méthode update afin que se soit seulement le propriétaire de l'article qui puisse le modifier

public function update(User $user, Post $post)
{
    return $user->id === $post->user_id;
}

Si l'id de $user correspond au user_id de l'article $post, alors la condition retournera true et l'utilisateur pourra modifier l'article

Enregistrement des Policies

Si vous respecter les conventions, les Policies sont auto-découvertes par Laravel, et il n'y a pas besoin de lire ce paragraphe :)

Pour cela il faut que le dossier Policies soit sous le répertoire contenant les modèles et le nom doit correspondre à celui du modèle. Dans notre exemple, nous avons respecté ces conventions.

Si ces conventions ne sont pas respectées, il faut modifier le fichier /app/Providers/AuthServiceProvider.php en ajoutant le use \App\Post et en complétant l'attribut $policies

...
use App\Post;
...
protected $policies = [
    Post::class => PostPolicy::class,
];

Filtre pour l'admin

Si on souhaite que l'admin puisse accéder à n'importe quelle action malgré la présence des Policies, on peut ajouter une méthode before() à la Class de Policies

...
public function before($user, $ability)
{
    if ($user->isAdmin()) {
        return true;
    }
}
...

Autoriser les actions des contrôleurs

Maintenant que la Policies est en place, on peut ajuster le contrôleur PostController afin d'autoriser l'action update seulement au propriétaire de l'article

...
public function update(Post $post, Request $request)
{
    $this->authorize('update', $post);
...

Autorisation dans les fichiers de vue Blade

Dans un vue, on peut maintenant utiliser

@can('update', $post)
    <!-- L'utilisateur peut éditer l'article -->
@elsecan('create', App\Post::class)
    <!-- L'utilisateur peut créer l'article -->
@endcan

@cannot('update', $post)
    <!-- L'utilisateur ne peut pas éditer l'article -->
@elsecannot('create', App\Post::class)
    <!-- L'utilisateur ne peut pas créer l'article -->
@endcannot