2017-06-19 2 views
0

Bei einer Benutzeraktion zeige ich, ob der angemeldete Benutzer das Recht hat, diesen Benutzer zu sehen. Also habe ich einen UserVoter erstellt. Aber wenn ich versuche, den Benutzer in der URL zum Voter Annotation mit definierten passieren, erhalte ich den angemeldeten Benutzer sowohl $subject und $token->getUser()Symfony UserVoter ruft den aktuell angemeldeten Benutzer an Stelle des Benutzers in der URL

mit der Wenn ich meine var name in der Aktion ändern, es funktioniert gut ($ user - > $ foo).

Wissen Sie, wie kann ich tun, um meinen Var-Namen nicht zu ändern?

Controller:

/** 
* Finds and displays a user entity. 
* 
* @Method("GET") 
* @Route("/{id}/", name="authenticated_user_show", requirements={"id": "\d+"}) 
* @ParamConverter("user", class="AppBundle:User") 
* @Security("is_granted('SHOW', user)") 
*/ 
public function showAction(User $user) 
{ 

Und Voter:

protected function voteOnAttribute($attribute, $subject, TokenInterface $token) 
{ 
    $user = $token->getUser(); 

    if (!$user instanceof User) { 
     // the user must be logged in; if not, deny access 
     return false; 
    } 

    if ($user->hasRole(User::ROLE_SUPER_ADMIN)) { 
     // if super admin, can do everything 
     return true; 
    } 

    // you know $subject is an User object, thanks to supports 
    /** @var User $userSubject */ 
    $userSubject = $subject; 

    switch ($attribute) { 
     case self::SHOW: 
      return $this->canShow($userSubject, $user); 
     case self::EDIT: 
      return $this->canEdit($userSubject, $user); 
    } 

    throw new \LogicException('This code should not be reached!'); 
} 


private function canShow(User $userSubject, User $user) : bool 
{ 
    if ($user->getClient() === $userSubject->getClient()) { 
     // if they are in the same client 
     return true; 
    } 

    return false; 
} 

private function canEdit(User $userSubject, User $user, TokenInterface $token) : bool 
{ 
    if (
     $this->decisionManager->decide($token, [User::ROLE_ADMIN]) && 
     $user->getClient() === $userSubject->getClient() 
     ) { 
     // if the user and the admin belong to the same client 
     return true; 
    } elseif (
     $this->decisionManager->decide($token, [User::ROLE_MANAGER]) && 
     $this->userManager->hasEstablishmentInCommon($user, $userSubject) 
     ) { 
     // if the user and the manager are linked to the same establishment 
     return true; 
    } 

    return false; 
} 
+0

Ihr Code sieht soweit ganz gut aus. Können Sie überprüfen, dass Sie die Benutzer nicht verwirren (Reihenfolge der Parameter auf $ this-> canShow und $ this-> canEdit)? Können Sie den Code $ this-> canShow $ this-> canEdit teilen? Ich werde wahrscheinlich umbenennen $ Benutzer für $ luggedUser, um ein wenig zu verdeutlichen – albert

+0

Danke für die Antwort, ich habe die Frage bearbeiten, um Ihnen $ this-> canEdit() zu zeigen. Aber die Probleme kommen von woanders, denn wenn ich 'dump ($ user)' und 'dump ($ userSubject)' in der voteOnAttribute Funktion mache, sind beide der aktuell geloggte Benutzer. – Theolephant

Antwort

0

Unter der Annahme, dass Sie nicht den angemeldeten Benutzers zu sehen versuchen, werde ich der Meinung, dass Sie einen Konflikt mit den Variablen in der Sicherheits Anmerkung haben Kontext:

https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/security.html Die Sicherheitsanmerkung hat Zugriff auf die folgenden Variablen:

  • token: Der aktuelle Sicherheitstoken
  • Benutzer: Das aktuelle Benutzerobjekt
  • Anfrage: Die Anforderungsinstanz
  • Rollen: die Benutzerrollen; und alle Anfrage Attribute.

Um zu beheben, ändern Sie den Namen des Benutzers, damit Sie den Konflikt vermeiden können.

/** 
* Finds and displays a user entity. 
* 
* @Method("GET") 
* @Route("/{id}/", name="authenticated_user_show", requirements={"id": 
    "\d+"}) 
* @ParamConverter("showUser", class="AppBundle:User") 
* @Security("is_granted('SHOW', showUser)") 
*/ 
public function showAction(User $showUser) 
Verwandte Themen