Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Registering user with FOSUserBundle without logging the user in

I'm trying to implement registeration with FOSUserBundle. I want an admin to be able register a new user and this I've done simply by changing registration to a firewalled route (/admin/register prefix).

I created a custom registration form type and registered it as a service as instructed here: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/overriding_forms.md

I then hooked into the registration events based on this: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/controller_events.md

My listener looks like this:

use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;


class RegistrationListener implements EventSubscriberInterface
{
    private $router;

    public function __construct(UrlGeneratorInterface $router)
    {
        $this->router = $router;
    }

    /**
     * {@inheritDoc}
     */
    public static function getSubscribedEvents()
    {
        return array(
            FOSUserEvents::REGISTRATION_COMPLETED => 'onRegisterDone',
            FOSUserEvents::REGISTRATION_CONFIRMED => 'onRegisterDone',
            FOSUserEvents::RESETTING_RESET_COMPLETED => 'onRegisterDone',
        );
    }

    public function onRegisterDone(FilterUserResponseEvent $event)
    {
        $url = $this->router->generate('admin_panel');

        //$event->setResponse(new RedirectResponse($url));
    }
}

The FilterUserResponseEvent does not have the setResponse method, so I'm just letting it run through. I thought that subscribing to this event would override the default FOS\UserBundle\EventListener\AuthenticationListener subscribed events and stop the user from being logged in, but the new user still gets logged in.

Is it possible to prevent the authentication, or should I just simply create a new form which would call an action to call User Manager?

like image 925
juuga Avatar asked Jun 11 '13 07:06

juuga


3 Answers

Had the same problem and this worked for me.

Comment out this line in overriden Registration Controller:

$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));

public function registerAction(Request $request)
{
    /** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
    $formFactory = $this->container->get('fos_user.registration.form.factory');
    /** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */
    $userManager = $this->container->get('fos_user.user_manager');
    /** @var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
    $dispatcher = $this->container->get('event_dispatcher');

    $user = $userManager->createUser();
    $user->setEnabled(true);

    $dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, new UserEvent($user, $request));

    $form = $formFactory->createForm();
    $form->setData($user);

    if ('POST' === $request->getMethod()) {
        $form->bind($request);

        if ($form->isValid()) {
            $event = new FormEvent($form, $request);
            $dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);

            $userManager->updateUser($user);

            if (null === $response = $event->getResponse()) {
                $url = $this->container->get('router')->generate('fos_user_registration_confirmed');
                $response = new RedirectResponse($url);
            }

            //comment below line to prevent login user after registration
            //$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));

            return $response;
        }
    }

    return $this->container->get('templating')->renderResponse('FOSUserBundle:Registration:register.html.'.$this->getEngine(), array(
            'form' => $form->createView(),
    ));
}
like image 51
Strabek Avatar answered Nov 19 '22 03:11

Strabek


You can also override Registration Controller to do so. (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/overriding_controllers.md)

You just need to delete one line $this->authenticateUser($user); and user will not be authenticated after registration.

Overriding controller for only delete this line is not a good approach. But if you cannot override right listener and hook the right moment it can be the easiest way to do your task as quickly as possible;-)

like image 33
Michael Sivolobov Avatar answered Nov 19 '22 04:11

Michael Sivolobov


This is what I did to redirect to the admin panel. I used the REGISTRATION_SUCCESS event (which uses FormEvent instead of FilterUserResponseEvent).

use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;


class RegistrationListener implements EventSubscriberInterface
{
    private $router;

    public function __construct(UrlGeneratorInterface $router)
    {
        $this->router = $router;
    }

    public static function getSubscribedEvents()
    {
        return array(
            FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess',
        );
    }

    public function onRegistrationSuccess(FormEvent $event)
    {
        $url = $this->router->generate('admin_users');
        $event->setResponse(new RedirectResponse($url));
    }
}

In order to prevent the authentication I had to override the AuthenticationListener as described in https://stackoverflow.com/a/23969485/5074443. Here is my AuthenticationListener:

use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\EventListener\AuthenticationListener as FOSAuthenticationListener;

class AuthenticationListener extends FOSAuthenticationListener
{
    public static function getSubscribedEvents()
    {
        return array(
            // do not authenticate after registration
            // FOSUserEvents::REGISTRATION_COMPLETED => 'authenticate',
            // FOSUserEvents::REGISTRATION_CONFIRMED => 'authenticate'
            FOSUserEvents::RESETTING_RESET_COMPLETED => 'authenticate',
        );
    }
}
like image 2
epecourt Avatar answered Nov 19 '22 03:11

epecourt