pouvez vous m'aider pour check le role de l utilisateur s il est admin il peut tout modifier sinn il peut pas je suis débutante sur cakephp 3

39 réponses


IceDeath
Réponse acceptée

Ok mais les utilisateur normaux peuvent pas?
Sinon ce serait normal que les autheurs puissent le faire (après tu fais comme tu le sens), sinon tu peux utiliser les sessions pour aller "plus vite" mais sinon test ça et dis moi si ça marche

    public function edit($id = null){
        $article = $this->Articles->get($id);
        if($this->Auth->user('role') == 'admin') {
            if ($this->request->is(['post', 'put'])) {
                $this->Articles->patchEntity($article, $this->request->data);
                $article->user_id = $this->Auth->user('id');
                if ($this->Articles->save($article)) {
                    $this->Flash->success(__('Votre article a été mis à jour.'));
                    return $this->redirect(['action' => 'index']);
                }
                $this->Flash->error(__('Impossible de mettre à jour votre article.'));
            }
        } else {
            $this->Flash->error(__("Impossible d'éditer cet articles car vous n'êtes pas administrateur."));
        }
        $this->set('article', $article); 
    }

Lol, je pensais que tu avais déjà une base :)

Bref, en gros ce que tu dois faire c'est déjà attribuer des rôles à tes utilisateurs. Dans ta table users tu peux rajouter la colonne role, et pour un admin tu lui attribuera la valeur "admin".

On est parti :

Dans ton AppController.php tu dois avoir dans ta méthode initialize ceci

public function initialize()
{
    $this->loadComponent('Auth', [
        'authorize' => ['Controller']      
    ]);
}

public function isAuthorized($user)
{
    // les admins auront accès à tout
    if (isset($user['role']) && $user['role'] === 'admin') {
        return true;
    }

    // Par défaut refuser
    return false;
}

Ca charge le component Auth et ça indique que l'autorisation se fait au niveau des controllers.

Dans tes autres controller tu devras autoriser les autres users pour les actions :

public function beforeFilter(Event $event)
{
    parent::beforeFilter($event);   
    $this->Auth->allow(['index', 'view']);
}

Dans cette configuration :

  • les admins peuvent tout faire
  • les non connecté et utilisateurs peuvent accéder à index et view

Bon courage

Houdette
Auteur

merci @connected mais comment ajouter la condition if role=admin autoriser le tout ?

C'est ce que retour cette méthode qui est important.
Si elle retourne true, ça va autoriser l'utilisateur à exécuter l'action. Dans le cas contraire, elle retroune false, ça va bloquer l'action.
Cake le gère automatiquement, et il le fait très bien :)

Tu as un exemple de blog sur la doc, tu as l'authentification avec !

Houdette
Auteur

@connected mais j'ai essayé toute à l'heure et elle laisse tous les utilisateurs modifier donc elle ne check pas les roles

Houdette
Auteur

et pour ajouter un utilisateur normal author ca me donne cette erreur : Unable to call method "" in "default" provider for field "role"

Houdette
Auteur

et meme pour un admin c bizarre

Prenons les choses dans l'ordre :

  • as-tu bien la colonne role dans la table users ?
  • comment tu fais pour rajouter ton utilisateur, quel est le code ?
Houdette
Auteur

oui j'ai la colonne role dans la table user

Houdette
Auteur

public function add()
{
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->success(("L'utilisateur a été sauvegardé."));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(
("Impossible d'ajouter l'utilisateur."));
}
$this->set('user', $user);
}

@connected mais j'ai essayé toute à l'heure et elle laisse tous les utilisateurs modifier donc elle ne check pas les roles

Est-ce que tu as bien rajouté dans ma méthode initialize de ton AppController le code suivant :

$this->loadComponent('Auth', [
        'authorize' => ['Controller']      
    ]);

Il ne faut pas qu'il y ai d'autres références à Auth dans ton code...

Houdette
Auteur

oui je l'ai rajouté mais j'ai gardé ce que j'avais avant
$this->loadComponent('Flash');

    $this->loadComponent('Auth', [
        'authenticate' => [
            'Form' => [
                'fields' => ['username' => 'email', 'password' => 'password']]]

]);
    $this->loadComponent('Auth', [
        'authorize' => ['Controller']
    ]); 
    dois je le supprimer?

et pour ajouter un utilisateur normal author ca me donne cette erreur : Unable to call method "" in "default" provider for field "role"

Tu as du définir des règles de validation non ?

Houdette
Auteur

non comme quoi ?

Tu ne dois avoir qu'un seul loadComponent('Auth', ...)
Ce qui donne

  $this->loadComponent('Auth', [
                        'authenticate' => [
                          'Form' => [
                            'fields' => ['username' => 'email', 'password' => 'password']]],
                        'authorize' => ['Controller']
                       ]);

Essaye de remplacer ta méthode add par :

public function add()
  {
    $user = $this->Users->newEntity();
    if ($this->request->is('post')) {
      $user = $this->Users->patchEntity($user, $this->request->data, ['validate' => false]);
      if ($this->Users->save($user)) {
        $this->Flash->success(("L'utilisateur a été sauvegardé."));
        return $this->redirect(['action' => 'index']);
      }
      $this->Flash->error(("Impossible d'ajouter l'utilisateur."));
    }
    $this->set('user', $user);
  }

J'ai désactivé la validation pour répondre à ta question. On va voir ce que ça donne lol

Houdette
Auteur

@connected merci pour ton aide mais ça me donne toujours la meme erreur meme si je n ai laissé qu une seule loadcomponent et voici l erreur qui me donne :
Unable to call method "" in "default" provider for field "role" InvalidArgumentException
Et quand j'ai changé la méthode add ça me donne cette erreur :
Call to a member function success() on a non-object

Salut,

est-ce que je peux voir où tu en es, le code, dans ton AppController.php et ta méthode add de ton UsersController ?

Pour la seconde erreur, à mon avis tu ne charge pas le component flash, du coup tu es sur un objet null.

Est-ce que tu as cette ligne dans ton AppController ?

$this->loadComponent('Flash');

Elle doit se trouver dans ta méthode initialize, si ce n'est pas le cas il faut le déplacer ou bien l'ajouter.

Houdette
Auteur

Bonjour,
oui la ligne $this->loadComponent('flash'); est bien dans mon AppController
voici mon code :
AppController.php :
<?
namespace App\Controller;

use Cake\Controller\Controller;
use Cake\Event\Event;

class AppController extends Controller
{
//...

public function initialize()
{
    $this->loadComponent('Flash');

    $this->loadComponent('Auth', [
        'authenticate' => [
            'Form' => [
                'fields' => ['username' => 'email', 'password' => 'password']]]

]);
    $this->loadComponent('Auth', [
        'authorize' => ['Controller']
    ]);
}

public function isAuthorized($user)
{
    // les admins auront accès à tout
    if (isset($user['role']) && $user['role'] === 'admin') {
        return true;
    }

    // Par défaut refuser
    return false;
}

public function beforeFilter(Event $event)
{
    $this->Auth->allow(['index', 'view', 'display']);
}

}
la mthode add dans userController.php :
public function add()

{
    $user = $this->Users->newEntity();
    if ($this->request->is('post')) {
        $user = $this->Users->patchEntity($user, $this->request->data, ['validate' => false]);
        if ($this->Users->save($user)) {
            $this->Flash->success(__("L'utilisateur a été sauvegardé."));
            return $this->redirect(['action' => 'index']);
        }
        $this->Flash->error(("Impossible d'ajouter l'utilisateur."));
    }
    $this->set('user', $user);
}

maintenant je peux ajouter des utilisateurs en modifiant le role mais y a pas une vérification de code soit l admin soit l author ils peuvent rentrer dans la méthode edit() de Articles et porter des modification et c pas ce que je veux puisque y a que les admin qui peuvent modifier les articles .
Merci @connected de bien vouloir me répondre :)

Ok, merci.
Mais je n'arrive toujours pas à suivre, à quelle moment tu as les messages d'erreur que tu cites plus haut ?
Sur qu'elle action exactement.

Salut, déjà:

public function initialize()
{
    $this->loadComponent('Flash');

    $this->loadComponent('Auth', [
        'authenticate' => [
            'Form' => [
                'fields' => ['username' => 'email', 'password' => 'password']]]

]);
    $this->loadComponent('Auth', [
        'authorize' => ['Controller']
    ]);
}

tu mets 2x le loadComponent('Auth',[ à la place fait

public function initialize()
{

    $this->loadComponent('Flash');

    $this->loadComponent('Auth', [
        'authorize' => ['Controller'],
        'authenticate' => [
            'Form' => [
                'fields' => ['username' => 'email', 'password' => 'password']]]

]);
}

Si tu veux utiliser ces fonctions dans tes controllers tu fais

    public function beforeFilter(Event $event){
        parent::beforeFilter($event);
        $this->Auth->allow(); //ici mets les fonction que les utilisateurs n'ont pas l'autorisation d'acceder que si ils sont admin
    }

    public function initialize(){
        parent::initialize();
        //ici si il faut que tu charge d'autre cmponent spécifique au Controller
    }

par exemple si tu veux dans ton ArticlesController tu fais

    public function beforeFilter(Event $event){
        parent::beforeFilter($event);
        $this->Auth->allow('index', 'view'); //ici les seules action possible sont soit de d'accéder à la fonction index soit view, pour le reste il faut être admin.
    }

En espérant t'avoir aidé.

Houdette
Auteur

ça me donne pas des erreurs pour le moment mais tous les utilisateurs peuvent modifier les articles soit les admin soit les author c'est ça e poblème .

@LeDevDu50, c'est une mauvaise idée de mettre la vérification du rôle dans la méthode edit.

Ce qu'il faut faire, @Houdette, c'est d'utiliser les beforeFilter.

Dans AppController le beforeFilter va gérer l'accès pour l'ensemble de tes controleurs :
Exemple si tu mets ceci dans ton AppController :

  public function beforeFilter(Event $event){
        parent::beforeFilter($event);
        $this->Auth->allow('index', 'view'); 
    }

Tout le monde aura accès aux actions index et view de tous tes controleurs, même les personnes non connectées. Pour toutes les autres actions, personne n'y a accès.
Ensuite au niveau de ton controleur Article si tu rajoutes dans ton beforeFilter :

  public function beforeFilter(Event $event){
        parent::beforeFilter($event);
        if($this->Auth->user('role') == 'admin') {
            $this->Auth->allow('edit');
        }
    }

Seule les admins pourront editer. Pas besoin de faire la condition dans la méthode edit().

D'accord, mais pourquoi ce serait une mauvaise idée? personnes peut la modifier et ça vérifie si l'utilisateur est admin, certe ça va moins viter que ta méthode (je n'y avait pas pensé).

Houdette
Auteur

Merci pour votre aide
@connected j'ai fait ta méthode et le meme probleme meme les utilisateurs standards peuvent modifier par contre j'ai essayé la méthode proposée par @LeDevDu50 et ça fonctionne bien :)

Bon si je comprends bien ton problème est résolue?

Houdette
Auteur

oui oui c bon seuls les admins peuvent modifier maintenant :)

@LeDevDu50, ta proposition de code que Houdette à marqué comme résolu, est partiellement fausse.
Pour commencer, concernant l'identifiant de l'auteur de l'article, seul l'administrateur a accès à l'action edit du controller, dans le cas ou l'auteur de l'article n'est pas l'administrateur, l'identifiant de l'auteur sera remplacé par celui de l'administrateur.
Du coup, tous les auteurs autre que l'administrateur, perdront la légitimité de leurs articles.
Ensuite, vu que tu mets un message flash dans le cas ou l'utilisateur n'est pas autorisé a accéder à l'action, autant le rediriger dans une vue autorisée aux non administrateur, car là, tu ne veux pas lui autoriser l'action, mais il y reste malgré tout.
Il ne suffit pas de juste lui empêcher de pouvoir sauvegarder les données soumises via le formulaire, mais aussi lui empêcher de pouvoir y accéder.

Pour le user id j'ai juste repris le code de l'action edit de la doc et j'ai rajouté le if, je donnais juste un exemple et pour le message c'est pas bien grave elle a juste à faire le redirect elle même. C'est pas bien difficile.

@Houdette, si ma méthode ne fonctionne pas c'est qu'il y a doit y avoir des conflits avec ton code. Mais je suis convaincu que ma méthode est est plus "scalable" comme dirait les américains :)

Bon courage pour la suite.

Effectivement elle fonctionne chez moi aussi.

Houdette
Auteur

merci @connected oui peut etre qu il y a un probleme dans mon code mais je vous ai tout montré je sais pas pk ça n a pas fonctionné !

Houdette
Auteur

@connected et @LeDevDu50, j ai besoind de votre aide pour forgotten password si vous pouvez m'aider je serai reconnaissante.

Ok, tu as déjà commencé à réfléchir comment le faire? envoie d'email, token...?

j ai besoind de votre aide pour forgotten password si vous pouvez m'aider je serai reconnaissante.

Tu as déja créé un sujet pour ça, alors ne demandes pas de l'aide concernant un autre sujet que tu as créé sur celui-ci.

Houdette
Auteur

@LeDevDu50 oui j'ai déjà réfléchi et j'ai crée un sujet qui a comme titre forgotten password j'ai écris tout ce que j'ai pu faire pour l instant . Merci.
@Lartak :c'est un forum fait pour l'entraide peu importe ou j'écrit mon probleme et vaudrait mieux me répondre sur mon sujet que j'ai crée puisque tu l'as remarqué au lieu de m'écrire des remarques qui ne me serviront pas pour résoudre mon probleme .

c'est un forum fait pour l'entraide peu importe ou j'écrit mon probleme

Si tu penses comme ça, tu n'iras pas loin et je ne vois pas pourquoi nous devrions te répondre sur plusieurs de tes sujets pour le même problème.

Houdette
Auteur

@lartak personne n est obligé de me répondre j'ai demandé à ceux qui m ont aidé vraiment puisque leurs idées et propositions m'ont aidé par contre personne ne me cassera les cuilles et c'est ta deuxieme réponse inutile pour mes problemes alors merci de bien vouloir s'arreter :) on se dispute pas je demande de l'aide à ceux qui sont disponibles je cherche pas des problemes ici .