1<?php
2
3/*
4 * This file is part of the Silex framework.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Silex\Provider;
13
14use Silex\Application;
15use Silex\ServiceProviderInterface;
16use Symfony\Component\Security\Core\Authentication\Provider\RememberMeAuthenticationProvider;
17use Symfony\Component\Security\Http\Firewall\RememberMeListener;
18use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices;
19use Symfony\Component\Security\Http\RememberMe\ResponseListener;
20
21/**
22 * Remember-me authentication for the SecurityServiceProvider
23 *
24 * @author Jérôme Tamarelle <jerome@tamarelle.net>
25 */
26class RememberMeServiceProvider implements ServiceProviderInterface
27{
28    public function register(Application $app)
29    {
30        $app['security.remember_me.response_listener'] = $app->share(function () {
31            return new ResponseListener();
32        });
33
34        $app['security.authentication_listener.factory.remember_me'] = $app->protect(function ($name, $options) use ($app) {
35            if (empty($options['key'])) {
36                $options['key'] = $name;
37            }
38
39            if (!isset($app['security.remember_me.service.'.$name])) {
40                $app['security.remember_me.service.'.$name] = $app['security.remember_me.service._proto']($name, $options);
41            }
42
43            if (!isset($app['security.authentication_listener.'.$name.'.remember_me'])) {
44                $app['security.authentication_listener.'.$name.'.remember_me'] = $app['security.authentication_listener.remember_me._proto']($name, $options);
45            }
46
47            if (!isset($app['security.authentication_provider.'.$name.'.remember_me'])) {
48                $app['security.authentication_provider.'.$name.'.remember_me'] = $app['security.authentication_provider.remember_me._proto']($name, $options);
49            }
50
51            return array(
52                'security.authentication_provider.'.$name.'.remember_me',
53                'security.authentication_listener.'.$name.'.remember_me',
54                null, // entry point
55                'remember_me',
56            );
57        });
58
59        $app['security.remember_me.service._proto'] = $app->protect(function ($providerKey, $options) use ($app) {
60            return $app->share(function () use ($providerKey, $options, $app) {
61                $options = array_replace(array(
62                    'name'                  => 'REMEMBERME',
63                    'lifetime'              => 31536000,
64                    'path'                  => '/',
65                    'domain'                => null,
66                    'secure'                => false,
67                    'httponly'              => true,
68                    'always_remember_me'    => false,
69                    'remember_me_parameter' => '_remember_me',
70                ), $options);
71
72                return new TokenBasedRememberMeServices(array($app['security.user_provider.'.$providerKey]), $options['key'], $providerKey, $options, $app['logger']);
73            });
74        });
75
76        $app['security.authentication_listener.remember_me._proto'] = $app->protect(function ($providerKey) use ($app) {
77            return $app->share(function () use ($app, $providerKey) {
78                $listener = new RememberMeListener(
79                    $app['security'],
80                    $app['security.remember_me.service.'.$providerKey],
81                    $app['security.authentication_manager'],
82                    $app['logger'],
83                    $app['dispatcher']
84                );
85
86                return $listener;
87            });
88        });
89
90        $app['security.authentication_provider.remember_me._proto'] = $app->protect(function ($name, $options) use ($app) {
91            return $app->share(function () use ($app, $name, $options) {
92                return new RememberMeAuthenticationProvider($app['security.user_checker'], $options['key'], $name);
93            });
94        });
95    }
96
97    public function boot(Application $app)
98    {
99        if (!isset($app['security'])) {
100            throw new \LogicException('You must register the SecurityServiceProvider to use the RememberMeServiceProvider');
101        }
102
103        $app['dispatcher']->addSubscriber($app['security.remember_me.response_listener']);
104    }
105}
106