i have a problem i dont know how to stop it. i have an infinite loop on a redirect route, i tried to redirect a user if he has not accept some condition
this is my code :
/**
* AcceptanceListener constructor.
* #param $router
* #param TokenStorageInterface $tokenStorage
* #param UserManager $userManager
* #param AuthorizationChecker $checker
*/
public function __construct(
$router,
TokenStorageInterface $tokenStorage,
UserManager $userManager,
AuthorizationChecker $checker
) {
$this->router = $router;
$this->tokenStorage = $tokenStorage;
$this->userManager = $userManager;
$this->role = $checker;
}
/**
* To checked all the routes
*
* #param GetResponseEvent $event
*/
public function onKernelRequest(GetResponseEvent $event)
{
$user = $this->tokenStorage->getToken()->getUser();
if ($this->role->isGranted('ROLE_USER')
&& !$this->userManager->hasAccepted($user)
) {
$this->redirect = $this->router->generate('accept_');
$event->setResponse(new RedirectResponse($this->redirect));
}
}
someone can help me please?
Check if the route is not the same, then redirect
public function onKernelRequest(GetResponseEvent $event)
{
$route_name = $event->getRequest()->get('_route');
if ($route_name != 'accept_') {
$user = $this->tokenStorage->getToken()->getUser();
if ($this->role->isGranted('ROLE_USER')
&& !$this->userManager->hasAccepted($user)
) {
$this->redirect = $this->router->generate('accept_');
$event->setResponse(new RedirectResponse($this->redirect));
}
}
}
Related
I'm trying to move my heavy treatment to Messenger.
It works but I would like to show a percentage of progress to my users.
I created a DownloadTask entity and I try to update it during the process but it doesn't work. My entity is not updated in the database.
Do you have any ideas?
I'm still learning, so I hope my code won't hurt your eyes too much.
<?php
namespace App\MessageHandler;
use App\Message\GetSellerList;
use App\Repository\DownloadTaskRepository;
use App\Service\EbayDL;
use Doctrine\DBAL\ConnectionException;
use Doctrine\ORM\EntityManagerInterface;
use DTS\eBaySDK\Trading\Types\GetSellerListResponseType;
use GuzzleHttp\Promise;
use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
class GetSellerListHandler implements MessageHandlerInterface
{
/**
* #var EbayDL
*/
private $ebayDL;
/**
* #var EntityManagerInterface
*/
private $entityManager;
/**
* #var LoggerInterface
*/
private $logger;
/**
* #var \App\Entity\DownloadTask
*/
private $task;
/**
* #var DownloadTaskRepository
*/
private $downloadTaskRepository;
public function __construct(EbayDL $ebayDL, EntityManagerInterface $entityManager, DownloadTaskRepository $downloadTaskRepository, LoggerInterface $logger)
{
$this->ebayDL = $ebayDL;
$this->entityManager = $entityManager;
$this->logger = $logger;
$this->downloadTaskRepository = $downloadTaskRepository;
}
/**
* #throws ConnectionException
* #throws \Exception
* #throws \Throwable
*/
public function __invoke(GetSellerList $getSellerList): void
{
$task = $this->downloadTaskRepository->find($getSellerList->getDownloadTaskId());
$this->clearDatabase();
$listingInfos = $this->ebayDL->getInformation();
$totalNumberOfPages = $listingInfos['totalNumberOfPages'];
$promises = (function () use ($totalNumberOfPages) {
for ($page = 1; $page <= $totalNumberOfPages; ++$page) {
yield $this->ebayDL->getProductsByPageAsync($page);
}
})();
$eachPromise = new Promise\EachPromise($promises, [
'concurrency' => 6,
'fulfilled' => function (GetSellerListResponseType $response): void {
$products = $this->ebayDL->parseSellerListResponse($response);
foreach ($products as $product) {
try {
$this->entityManager->persist($product);
$this->entityManager->flush();
} catch (\Exception $e) {
$this->logger->error('Failed to store a product');
$this->logger->error($e->getMessage());
if (!$this->entityManager->isOpen()) {
// https://stackoverflow.com/questions/14258591/the-entitymanager-is-closed
$this->entityManager = $this->entityManager->create(
$this->entityManager->getConnection(),
$this->entityManager->getConfiguration()
);
}
}
}
},
]);
$eachPromise->promise()->wait();
$this->task
->setProgress(100)
->setCompletedAt(new \DateTime('NOW'));
$this->entityManager->flush();
}
/**
* #throws ConnectionException
* #throws \Doctrine\DBAL\DBALException
*/
private function clearDatabase(): void
{
$connection = $this->entityManager->getConnection();
$connection->beginTransaction();
try {
$connection->query('SET FOREIGN_KEY_CHECKS=0');
$connection->query('DELETE FROM product');
$connection->query('SET FOREIGN_KEY_CHECKS=1');
$connection->commit();
} catch (\Exception $exception) {
$connection->rollback();
}
}
}
Should
$task = $this->downloadTaskRepository->find($getSellerList->getDownloadTaskId());
be
$this->task = $this->downloadTaskRepository->find($getSellerList->getDownloadTaskId());
?
I have a problem with my method getDomain() becuase I got report ,,Call to a member function getDomain() on null''
This is my Entity ....
class Clinic
{
.............
/**
* #ORM\Column(type="string")
*/
private $domain;
..............
/**
* #return string
*/
public function getDomain()
{
return $this->domain;
}
/**
* #param string $domain
*/
public function setDomain($domain)
{
$this->domain = $domain;
}
...............
And this is my EventListener
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
$currentHost = $request->getHttpHost();
$c = $this->em
->getRepository('Mybundle:Clinic')
->findOneBy(['domain' => $currentHost]);
if (!$c) {
$c = $this->em
->getRepository('Mybundle:Clinic')
->findOneBy(['domain' => $this->baseHost]);
}
$this->router->getContext()->setParameter('_domain', $c->getDomain());
$this->cManager->setCC($c);
I have date in my database, please help me.
If $c is setted in your first call, variable called $clinic is never setted, but used in router call.
I'm creating an E-commerce app and I'm building a custom redirection with the Handler.
Let's say my user is on his shopping's cart and he is not logged. He validates his cart to continue the buying process. In this situation, My app redirect the user to the login page. But when He is finally logged I would like to redirect him to the previous route (ie the cart page).
(Sorry for my poor english, I hope you will understand what I say)
This is my AuthentificationSuccessHandler :
class AuthentificationSuccessHandler implements AuthenticationSuccessHandlerInterface
{
protected $router;
protected $security;
/**
* AfterLoginRedirection constructor.
* #param Router $router
* #param AuthorizationChecker $security
*/
public function __construct(Router $router, AuthorizationChecker $security)
{
$this->router = $router;
$this->security = $security;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
$session = $request->getSession();
if ($this->security->isGranted('ROLE_SUPER_ADMIN')) {
$response = new RedirectResponse($this->router->generate('_homepage_admin'));
} else {
$referer_url = $request->headers->get('referer');
$response = new RedirectResponse($referer_url);
}
$session->getFlashBag()->add('success', 'Connexion réussi !');
return $response;
}
As you can see, I use headers->get('referer'); like I saw in the documentation, but this is not working. The user is redirect to the login page (but the authentification works fine)
So i'm stuck right now..
Tell me if you need more code to help me for my issue.
Any clues or advices ?
Thanks.
Well, I found a solution, I don't know if it's the better way but at least it's works.
So : into my listener I storage a attribute in the session's object, This attribue is update if the user is on a path in my list.
My Listener :
class RedirectionListener
{
/**
* RedirectionListener constructor.
* #param ContainerInterface $container
* #param Session $session
*/
public function __construct(ContainerInterface $container, Session $session)
{
$this->session = $session ;
$this->router = $container->get('router') ;
$this->securityContext = $container->get('security.context') ;
}
/**
* #param GetResponseEvent $event
*/
public function onKernelRequest(GetResponseEvent $event){
$request = $event->getRequest() ;
$list_route = array('_cart', '_category', '_delivery','_validate','_product','_homepage');
$route = $request->attributes->get('_route') ;
$route_params = $request->attributes->get('_route_params') ;
if(in_array($route, $list_route)){
$this->setRouteSession($request, $route, $route_params);
}
if($route == "_delivery" || $route =="_validate"){
if ($this->session->has('cart')){
if(count($this->session->get('cart')) == 0){
$this->session->getFlashBag()->add('info', 'Votre panier étant vide, vous ne pouvez pas continuer le processus d\'achat ');
$event->setResponse(new RedirectResponse($this->router->generate('_cart')));
}
}
if(!is_object($this->securityContext->getToken()->getUser())){
$this->session->getFlashBag()->add('info', 'Vous devez vous identifier');
$event->setResponse(new RedirectResponse($this->router->generate('fos_user_security_login')));
}
}
}
/**
* #param $request
* #param $route
* #param null $param
*/
private function setRouteSession($request, $route, $param){
$session = $request->getSession() ;
$session->set('lastPath', array(
'route' => $route,
'params' => $param
));
}
}
My Handler :
public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
$session = $request->getSession();
if(!$session->has('lastPath')){
$route = '_homepage';
} else {
$route = $session->get('lastPath') ;
}
if ($this->security->isGranted('ROLE_SUPER_ADMIN')) {
$response = new RedirectResponse($this->router->generate('_homepage_admin'));
} else {
if($route['params'] != null){
$response = new RedirectResponse($this->router->generate($route['route'],$route['params']));
} else {
$response = new RedirectResponse($this->router->generate($route['route']));
}
}
$session->getFlashBag()->add('success', 'Connexion réussi !');
return $response;
}
after user is logged in correctly you can get the referer url using
$this->getRequest()->headers->get('referer')
i'm working on symfony2 project and i get this exception. anybody have an idea on what is causing it ?
Uncaught exception 'Symfony\Component\Security\Core\Exception\AccessDeniedException' with message 'Access Denied' in /data/apache/www/emploipublic-sf/vendor/symfony/symfony/src/Symfony/Component/Security/Http/Firewall/AccessListener.php:70\n
class AccessListener implements ListenerInterface
{
private $context;
private $accessDecisionManager;
private $map;
private $authManager;
private $logger;
public function __construct(SecurityContextInterface $context, AccessDecisionManagerInterface $accessDecisionManager, AccessMapInterface $map, AuthenticationManagerInterface $authManager, LoggerInterface $logger = null)
{
$this->context = $context;
$this->accessDecisionManager = $accessDecisionManager;
$this->map = $map;
$this->authManager = $authManager;
$this->logger = $logger;
}
/**
* Handles access authorization.
*
* #param GetResponseEvent $event A GetResponseEvent instance
*/
public function handle(GetResponseEvent $event)
{
if (null === $token = $this->context->getToken()) {
throw new AuthenticationCredentialsNotFoundException('A Token was not found in the SecurityContext.');
}
$request = $event->getRequest();
list($attributes, $channel) = $this->map->getPatterns($request);
if (null === $attributes) {
return;
}
if (!$token->isAuthenticated()) {
$token = $this->authManager->authenticate($token);
$this->context->setToken($token);
}
if (!$this->accessDecisionManager->decide($token, $attributes, $request)) {
throw new AccessDeniedException(); // this is line 70
}
}
}
Look at your security.yml file (app/config/security.yml).
You may have some secure path which you do not have access to. Check out
security -> access_control
section.
How to manage Full authentication is required to access this resource.?
I want to redirect user when he is not authenticated.
I have custom uthenticater which authenticate user depending on session data, and i want to redirect user when hes not authenticatet.
My authenticator class:
/**
* #Service("sso_authenticator")
*/
class SsoAuthenticator implements SimplePreAuthenticatorInterface
{
/**
* #var SsoUserProvider
*/
protected $userProvider;
/**
* #InjectParams({
* "userProvider" = #Inject("sso_user_provider")
* })
*/
public function __construct(SsoUserProvider $userProvider)
{
$this->userProvider = $userProvider;
}
public function createToken(Request $request, $providerKey)
{
$user = $request->getSession()->get('sso_user');
if (!$user) {
throw new BadCredentialsException('No user found');
}
return new PreAuthenticatedToken(
'anon.', $user, $providerKey
);
}
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
$user = $token->getCredentials();
if (!is_array($user)) {
$user = $token->getUser();
}
if (!$user) {
throw new AuthenticationException('User does not exist.');
}
$ssoUser = $this->userProvider->loadUser($user);
return new PreAuthenticatedToken(
$ssoUser, $user, $providerKey, $ssoUser->getRoles()
);
}
public function supportsToken(TokenInterface $token, $providerKey)
{
return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
}
}
i set the login path to logout path like this:
secured_area:
form_login:
login_path : main_user_logout
then i wrote custom logout handler:
/**
* #Service("sso_authentication_handler")
*/
class SsoAuthenticationHandler implements LogoutSuccessHandlerInterface
{
/**
* #var Router
*/
private $router;
/**
* #var array
*/
protected $ssoUrls;
/**
* #InjectParams({
* "ssoUrls" = #Inject("%wordpress_sso%"),
* "router" = #Inject("router")
* })
*/
public function __construct(array $ssoUrls, Router $router)
{
$this->ssoUrls = $ssoUrls;
$this->router = $router;
}
public function onLogoutSuccess(Request $request)
{
$locale = $request->getLocale();
if ($locale === 'pl') {
$url = $this->ssoUrls[$locale];
} else {
$url = $this->ssoUrls['en'];
}
$url .= '?returnUrl=' . $this->router->generate('main');
return new RedirectResponse($url);
}
}
so with this combination i achive behavior like when youser is not authenticated or when he logout i will redirect him to other site to login, in my example to wordpress.