Witam. Chciałem się zapytać czy jest możliwe dodanie nowej funkcji do klasy Security. Chodzi mi o utworzenie funkcji podobnej do is_granted() z tym że ma ona sprawdzać czy ranga użytkownika o danym id ma dostęp do danej metody kontrolera. Znalazłem artykuły jak tworzyć własne adnotacje lecz nie znalazłem nic na temat mojego problemu. Oczywiście mógłbym utworzyć metodę w kontrolerze, która sprawdzałaby id rangi użytkownika lecz zależy mi na estetyce i chciałbym aby to wszystko znalazło się w PHP DOC.
Jeśli zależy Ci na estetyce to zapomnij, że coś takiego jak adnotacje (jeśli wpływają na działanie aplikacji, konfigurują cokolwiek itp.) w ogóle istnieje.
Oczywiscie... Musisz napisac class ktora dziedziczy po Security. W tej klasie dodajesz swoja method do sprawdzenia czy user ma dostep do ackji controllera.
Zostaje nadpisanie config symfony zeby Container wywowal twoja classe zamiast default... no i phpunit ;D
Nie wiem dokładnie co chcesz osiągnąć, ale może uda się to zrobić za pomocą https://symfony.com/doc/current/security/voters.html ?
Dzięki za pomoc. Athabus zrobilem to przy pomocy Voterów i raczej nie będzie potrzebne inne rozwiązanie. Jest mi to potrzebne do ustalania dostępu do danej akcji dla id grupy użytkownika z bazy danych ( administrator ma dostęp do wszystkich akcji, moderator do wybranych itd.) i administrowania dostępem poprzez bazę danych. Dodatkowo udało mi się stworzyć dodawanie indywidualnych uprawnień do akcji dla danego użytkownika. Jutro postaram się wrzucić moje rozwiązanie.
Poniżej udostępniam voter sprawdzający uprawnienia do akcji dla rangi użytkownika oraz uprawnienia do akcji dla id użytkownika. Voter operuje na dwóch tabelach. Jeżeli nie zostanie znalezione id rangi użytkownika w jednej tabeli to szuka id uprawnionego użytkownika w drugiej tabeli.
<?php /** * Created by PhpStorm. * User: E * Date: 23.09.2018 * Time: 19:54 */ namespace AppBundle\Security; use AppBundle\Entity\Pageroutes; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\Voter\Voter; class RankroutesVoter extends Voter { const EDIT = 'edit'; private $entityManager; private $request; public function __construct(EntityManagerInterface $entityManager, RequestStack $requestStack) { $this->entityManager = $entityManager; $this->request = $requestStack->getCurrentRequest()->attributes->get('_route'); } /** * Determines if the attribute and subject are supported by this voter. * * @param string $attribute An attribute * @param mixed $subject The subject to secure, e.g. an object the user wants to access or any other PHP type * * @return bool True if the attribute and subject are supported, false otherwise */ protected function supports($attribute, $subject) { if (!http://www.php.net/in_array($attribute, http://www.php.net/array(self::EDIT))) { return false; } return true; } /** * Perform a single access check operation on a given attribute, subject and token. * It is safe to assume that $attribute and $subject already passed the "supports()" method check. * * @param string $attribute * @param mixed $subject * @param TokenInterface $token * * @return bool */ protected function voteOnAttribute($attribute, $subject, TokenInterface $token) { //get current user $user = $token->getUser(); //get repository $pageroutes = $this->entityManager->getRepository(Pageroutes::class); //check that logged user rank is granted to actual request route $findroute = $pageroutes->findPageroutesRankRoute($user, $this->request); //check that logged user id is granted to actual request route $finduserroute = $pageroutes->findUserranksRankRoute($user, $this->request); $getPageroutesData = null; foreach($findroute as $userRankId) { foreach($userRankId->getRankid() as $fielddata) { $getPageroutesData = $fielddata; } } foreach($finduserroute as $userRankId) { $getPageroutesData = $userRankId; } switch ($attribute) { case self::EDIT: // if the user rank is granted to pageroute allow them to edit page if ($user->getRankid() === (object)$getPageroutesData) { return true; } // if the user id is granted to pageroute allow them to edit page if ($user === (object)$getPageroutesData) { return true; } return false; break; } return false; } }
/** * @param Users $users * @param $string * @return array */ public function findPageroutesRankRoute(Users $users, $string) { return $this->getEntityManager() ->createQuery( "SELECT p FROM AppBundle:Pageroutes p LEft Join p.rankid a WHERE a.rankid = :rankid And p.routename = :routename" ) ->setParameter("rankid", $users->getRankid()) ->setParameter("routename", $string) ->getResult(); } /** * @param Users $users * @param $string * @return array */ public function findUserranksRankRoute(Users $users, $string) { return $this->getEntityManager() ->createQuery( "SELECT u FROM AppBundle:Users u LEft Join u.routeid r WHERE u.userid = :userid And r.routename = :routename" ) ->setParameter("userid", $users->getUserid()) ->setParameter("routename", $string) ->getResult(); }
Nie koniecznie , mozesz stworzyc mape nazw ktora bedzie konfigurowalna i wtedy dasz np
[
edit => [
edit1,edit2
]
]
Wtedy w klasie votera jestes w stanie to ogarnac i nie musisz wszedzie zmieniac
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)