diff --git a/lib/Alchemy/Phrasea/Application/Root.php b/lib/Alchemy/Phrasea/Application/Root.php index 322eea51bb..dd5d1f13c7 100644 --- a/lib/Alchemy/Phrasea/Application/Root.php +++ b/lib/Alchemy/Phrasea/Application/Root.php @@ -56,6 +56,7 @@ use Alchemy\Phrasea\Controller\Prod\WorkZone; use Alchemy\Phrasea\Controller\Utils\ConnectionTest; use Alchemy\Phrasea\Controller\Utils\PathFileTest; use Silex\Application as SilexApp; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; @@ -68,6 +69,17 @@ return call_user_func(function($environment = null) { $app['firewall']->requireSetup($app); }); + $app->before(function(Request $request) use ($app) { + if (!$app->isAuthenticated() && $request->cookies->has('persistent')) { + try { + $auth = new \Session_Authentication_PersistentCookie($app, $request->cookies->get('persistent')); + $app->openAccount($auth, $auth->getSessionId()); + } catch (\Exception $e) { + + } + } + }); + $app->get('/', function(SilexApp $app) { if ($app['browser']->isMobile()) { return $app->redirect("/login/?redirect=lightbox"); diff --git a/lib/classes/Session/Authentication/PersistentCookie.class.php b/lib/classes/Session/Authentication/PersistentCookie.class.php index fd999431db..32d90f7169 100644 --- a/lib/classes/Session/Authentication/PersistentCookie.class.php +++ b/lib/classes/Session/Authentication/PersistentCookie.class.php @@ -42,25 +42,26 @@ class Session_Authentication_PersistentCookie implements Session_Authentication_ $this->app= $app; $this->persistent_cookie = $persistent_cookie; - $conn = $this->app['phraseanet.appbox']->get_connection(); - $sql = 'SELECT usr_id, session_id, nonce, token FROM cache WHERE token = :token'; - $stmt = $conn->prepare($sql); - $stmt->execute(array(':token' => $this->persistent_cookie)); - $row = $stmt->fetch(PDO::FETCH_ASSOC); - $stmt->closeCursor(); - if ( ! $row || count($row) == 0) { - throw new Exception_Session_WrongToken(); + $dql = 'SELECT s FROM Entities\Session s + WHERE s.token = :token'; + + $query = $app['EM']->createQuery($dql); + $query->setParameters(array('token' => $persistent_cookie)); + $session = $query->getOneOrNullResult(); + + if ( ! $session) { + throw new \Exception_Session_WrongToken('Persistent cookie value does not have any valid session'); } $string = $app['browser']->getBrowser() . '_' . $app['browser']->getPlatform(); - if (User_Adapter::salt_password($this->app, $string, $row['nonce']) !== $row['token']) { - throw new Exception_Session_WrongToken(); + if (\User_Adapter::salt_password($this->app, $string, $session->getNonce()) !== $session->getToken()) { + throw new \Exception_Session_WrongToken('Persistent cookie value is corrupted'); } - $this->user = User_Adapter::getInstance($row['usr_id'], $this->app); - $this->ses_id = (int) $row['session_id']; + $this->user = $session->getUser($app); + $this->ses_id = $session->getId(); return $this; } diff --git a/tests/Alchemy/Phrasea/Application/RootTest.php b/tests/Alchemy/Phrasea/Application/RootTest.php index 968f7b5000..8128b59d05 100644 --- a/tests/Alchemy/Phrasea/Application/RootTest.php +++ b/tests/Alchemy/Phrasea/Application/RootTest.php @@ -1,5 +1,10 @@ set('GV_allow_search_engine', $original_value, \registry::TYPE_BOOLEAN); } + + public function testNoPersistentCookie() + { + $app = self::$DI['app']; + $app->closeAccount(); + + $boolean = false; + + $app->get('/unit-test-route', function(Application $app) use (&$boolean) { + $boolean = $app->isAuthenticated(); + }); + + $client = new Client($app); + $client->request('GET', '/unit-test-route'); + + $this->assertFalse($boolean); + } + + public function testPersistentCookie() + { + $app = self::$DI['app']; + $app->closeAccount(); + + $browser = $this->getMockBuilder('\Browser') + ->disableOriginalConstructor() + ->getMock(); + + $browser->expects($this->any()) + ->method('getBrowser') + ->will($this->returnValue('Un joli browser')); + + $browser->expects($this->any()) + ->method('getPlatform') + ->will($this->returnValue('Une belle version')); + + $nonce = \random::generatePassword(16); + $string = $browser->getBrowser() . '_' . $browser->getPlatform(); + + $token = \User_Adapter::salt_password($app, $string, $nonce); + + $app['browser'] = $browser; + + $session = new \Entities\Session(); + $session->setUser(self::$DI['user']) + ->setBrowserName($browser->getBrowser()) + ->setBrowserVersion($browser->getVersion()) + ->setUserAgent('Custom UA') + ->setNonce($nonce) + ->setToken($token); + + $app['EM']->persist($session); + $app['EM']->flush(); + + $boolean = false; + + $app->get('/unit-test-route', function(Application $app) use (&$boolean) { + $boolean = $app->isAuthenticated(); + }); + + $cookieJar = new CookieJar(); + $cookieJar->set(new BrowserCookie('persistent', $token)); + + $client = new Client($app, array(), null, $cookieJar); + $client->request('GET', '/unit-test-route'); + + $this->assertTrue($boolean); + } }