IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

[ACL] bug quand isGranted() n'est pas valide


Sujet :

Symfony PHP

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2011
    Messages : 28
    Points : 24
    Points
    24
    Par défaut [ACL] bug quand isGranted() n'est pas valide
    Bonjour,

    J'ai une erreur qui me poursuit depuis quelques temps et je ne sais pas si c'est moi qui fait quelque chose faux ou si c'est un bug.

    J'ai une table avec des produits qui appartiennent à différents vendeurs ( FOSUserBundle) quand un vendeur ajoute un produit je crée des ACL comme indiqué dans la doc de symfony:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    if ('POST' === $request->getMethod()) {
                $form->bindRequest($request);
     
                if ($form->isValid()) {
                    $em = $this->getDoctrine()->getEntityManager();
                    $product->setVendor($vendor);
                    $vendor->addProducts($product);
                    $em->persist($product);
                    $em->persist($vendor);
                    $em->flush();
                    //acl for the product
                    $aclProvider = $this->get('security.acl.provider');
                    $objectIdentity = ObjectIdentity::fromDomainObject($product);
                    $acl = $aclProvider->createAcl($objectIdentity);
                    // retrieving the security identity of the page owner
                    $securityContext = $this->get('security.context');
                    $securityIdentity = UserSecurityIdentity::fromAccount($vendor);
                    // grant owner access Update acl
                    $acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER);
                    $aclProvider->updateAcl($acl);
                    //flash message success
                    $this->get('session')->setFlash('success', 'You have successfully added a product!');
     
                    return $this->redirect($this->generateUrl('page_show', array('username' => $vendor->getUsername())));
                }
    Jusque là tout fonctionne parfaitement.... Maintenant dans un autre Controller je veux authorizer seulement le propriétaire du produit à ajouter des photos du produit. Je veux donc utiliser la fonction isGranted... J'obtenais pas mal d'erreurs et j'ai donc décidé de la tester dans cette action:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        public function testAction() {
     
            $em = $this->getDoctrine()->getEntityManager();
            $securityContext = $this->get('security.context');
            $product = $em->getRepository('FldProductBundle:Product')->find(11);
            if (!$product) {
                throw $this->createNotFoundException('Unable to find Product entity.');
            }
            $grant = $securityContext->isGranted('EDIT', $product);
            var_dump($grant);
     
            return new Response('salut');
        }
    Tout fonctionne comme attendu quand je suis logué avec le propriétaire du produit 11 ( var_dump($grant); done boolean true et la réponse salut

    Maintenat quand je me logue avec quelqu'un qui n'est pas le proprio du produit 11 php semble tourner un moment ( mon portable lague un peu) et ensuite xdebug me donne cette erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
     
    ( ! ) Fatal error: Maximum execution time of 30 seconds exceeded in /.../vendor/symfony/src/Symfony/Component/Security/Acl/Domain/PermissionGrantingStrategy.php on line 172
    Call Stack
    #	Time	Memory	Function	Location
    1	0.0000	638888	{main}( )	../app_dev.php:0
    2	0.0505	2010448	Symfony\Component\HttpKernel\Kernel->handle( )	../app_dev.php:20
    3	0.0588	2640768	Symfony\Bundle\FrameworkBundle\HttpKernel->handle( )	../bootstrap.php.cache:547
    4	0.0588	2641776	Symfony\Component\HttpKernel\HttpKernel->handle( )	../classes.php:4832
    5	0.0588	2641776	Symfony\Component\HttpKernel\HttpKernel->handleRaw( )	../classes.php:3853
    6	0.2615	5471424	call_user_func_array ( )	../classes.php:3883
    7	0.2615	5471792	Fld\MediaBundle\Controller\ImageController->testAction( )	../classes.php:3883
    8	0.3607	5868128	Symfony\Component\Security\Core\SecurityContext->isGranted( )	../ImageController.php:57
    9	0.3608	5868696	Symfony\Component\Security\Core\Authorization\AccessDecisionManager->decide( )	../classes.php:5079
    10	0.3608	5868696	Symfony\Component\Security\Core\Authorization\AccessDecisionManager->decideAffirmative( )	../classes.php:5266
    11	0.3609	5868856	Symfony\Component\Security\Acl\Voter\AclVoter->vote( )	../classes.php:5298
    12	0.5432	6017584	Symfony\Component\Security\Acl\Domain\Acl->isGranted( )	../AclVoter.php:97
    13	0.5433	6017584	Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy->isGranted( )	../Acl.php:228
    14	0.5433	6017584	Symfony\Component\Security\Acl\Domain\PermissionGrantingStrategy->hasSufficientPermissions( )	../PermissionGrantingStrategy.php:59
    Variables in local scope (#14)
    $ace =
    &object(Symfony\Component\Security\Acl\Domain\Entry)[521]
    $aces =
    array
      0 => 
        &object(Symfony\Component\Security\Acl\Domain\Entry)[521]
    $acl =
    &object(Symfony\Component\Security\Acl\Domain\Acl)[523]
    $administrativeMode =
    boolean false
    $firstRejectedAce =
    null
    $masks =
    array
      0 => int 4
      1 => int 32
      2 => int 64
      3 => int 128
    $requiredMask =
    int 128
    $sid =
    object(Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity)[508]
      private 'role' => string 'IS_AUTHENTICATED_ANONYMOUSLY' (length=28)
    $sids =
    array
      0 => 
        object(Symfony\Component\Security\Acl\Domain\UserSecurityIdentity)[47]
          private 'username' => string 'dada' (length=4)
          private 'class' => string 'Fld\UserBundle\Entity\User' (length=26)
      1 => 
        object(Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity)[510]
          private 'role' => string 'ROLE_VENDOR' (length=11)
      2 => 
        object(Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity)[511]
          private 'role' => string 'ROLE_USER' (length=9)
      3 => 
        object(Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity)[506]
          private 'role' => string 'IS_AUTHENTICATED_FULLY' (length=22)
      4 => 
        object(Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity)[507]
          private 'role' => string 'IS_AUTHENTICATED_REMEMBERED' (length=27)
      5 => 
        object(Symfony\Component\Security\Acl\Domain\RoleSecurityIdentity)[508]
          private 'role' => string 'IS_AUTHENTICATED_ANONYMOUSLY' (length=28)
    alors que je m'attend a un false.... J'ai cherché un moment mais je ne comprend pas ce qui se passe... Est'ce que ça peut'être un bug? Merci d'avance

  2. #2
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2011
    Messages : 28
    Points : 24
    Points
    24
    Par défaut
    Apparemment l'erreur vient au moment ou la fonction de /vendor/symfony/src/Symfony/Component/Security/Acl/Domain/PermissionGrantingStrategy.php
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
        private function hasSufficientPermissions(AclInterface $acl, array $aces, array $masks, array $sids, $administrativeMode)
        {
            $firstRejectedAce  = null;
     
            foreach ($masks as $requiredMask) {
                foreach ($sids as $sid) {
                    foreach ($aces as $ace) {
                        if ($sid->equals($ace->getSecurityIdentity()) && $this->isAceApplicable($requiredMask, $ace)) {
                            if ($ace->isGranting()) {
                                if (!$administrativeMode && null !== $this->auditLogger) {
                                    $this->auditLogger->logIfNeeded(true, $ace);
                                }
     
                                return true;
                            }
     
                            if (null === $firstRejectedAce) {
                                $firstRejectedAce = $ace;
                            }
     
                            break 2;
                        }
                    }
                }
            }
     
            if (null !== $firstRejectedAce) {
                if (!$administrativeMode && null !== $this->auditLogger) {
                    $this->auditLogger->logIfNeeded(false, $firstRejectedAce);
                }
     
                return false;
            }
     
            throw new NoAceFoundException();
        }
    jette l'exception NoAceFoundException (Ligne 36) Si j'ai bien compris une ACE access control entrie dans les table générées par la commande init:acl c'est ce qui fait le lien entre l'identité de l'objet sur lequel on veut controller l'accès, l'identité de l'utilisateur et les droits qu'il a sur cet objet.

    Maintenant, quand je crée le produit, je ne rentre une ace que pour son propriétaire et pas pour le reste de tous les autres utilisateurs de mon application. Est'ce que isGranted s'attend à avoir pour chaque produit une entrée dans acl_entrie pour chaque utilisateur?

    Est'ce que mon problème vient de la ? Si oui comment trouver une sollution? Est'ce qu'il y a une manière de dire à symfony que si il n'existe pas le couple produitA/utilisateurB dans la table acl_entries alors par defaut l utilisateurB ne peut pas modifier le produitA?

    EDIT: Je pense pas que ce que j'ai dit au dessus aie du sens... On va pas écrire une ACE pour tous les utilisateurs... Bon je pense contourner le proble en faisant un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ($product -> getUser() == this->get('security.context')->getToken()->getUser() )
    mais je ne vois toujours pas pourquoi j'obtien cette erreur avec les ACL...

Discussions similaires

  1. Réponses: 11
    Dernier message: 08/05/2014, 18h10
  2. [XHTML] Mon espace web n'est pas valide XHTML 1.0 Strict!
    Par Olivier Regnier dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 02/06/2007, 15h29
  3. Connaitre les ports utilisés quand on n'est pas root
    Par Longrais dans le forum Administration système
    Réponses: 4
    Dernier message: 30/03/2007, 11h12
  4. Réponses: 7
    Dernier message: 27/03/2007, 20h52
  5. Réponses: 1
    Dernier message: 15/03/2007, 17h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo