From a7b36af01a894631edb1e0b67302ec3c51cf9733 Mon Sep 17 00:00:00 2001 From: Romain Neutron Date: Wed, 11 Sep 2013 16:02:55 +0200 Subject: [PATCH] Fix #1457 : EntityManager:clear should not be called in a controller --- .../Authentication/Phrasea/FailureManager.php | 9 ---- lib/classes/patch/3805.php | 2 +- .../Phrasea/FailureManagerTest.php | 52 ++++++++++++++++++- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/lib/Alchemy/Phrasea/Authentication/Phrasea/FailureManager.php b/lib/Alchemy/Phrasea/Authentication/Phrasea/FailureManager.php index 8ceca540d0..ef557949d0 100644 --- a/lib/Alchemy/Phrasea/Authentication/Phrasea/FailureManager.php +++ b/lib/Alchemy/Phrasea/Authentication/Phrasea/FailureManager.php @@ -113,18 +113,9 @@ class FailureManager ->findOldFailures('-2 months'); if (0 < count($failures)) { - $n = 0; foreach ($failures as $failure) { $this->em->remove($failure); - - if (0 === $n++ % 1000) { - $this->em->flush(); - $this->em->clear(); - } } - - $this->em->flush(); - $this->em->clear(); } } } diff --git a/lib/classes/patch/3805.php b/lib/classes/patch/3805.php index c11d64cc41..2a3d9daf49 100644 --- a/lib/classes/patch/3805.php +++ b/lib/classes/patch/3805.php @@ -56,7 +56,7 @@ class patch_3805 implements patchInterface $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); $stmt->closeCursor(); - $n = 0; + $n = 1; foreach ($rs as $row) { $date = Datetime::createFromFormat('Y-m-d h:i:s', $row['date']); diff --git a/tests/Alchemy/Tests/Phrasea/Authentication/Phrasea/FailureManagerTest.php b/tests/Alchemy/Tests/Phrasea/Authentication/Phrasea/FailureManagerTest.php index c2c13b2e60..ddb7d0f3ef 100644 --- a/tests/Alchemy/Tests/Phrasea/Authentication/Phrasea/FailureManagerTest.php +++ b/tests/Alchemy/Tests/Phrasea/Authentication/Phrasea/FailureManagerTest.php @@ -3,9 +3,11 @@ namespace Alchemy\Tests\Phrasea\Authentication\Phrasea; use Alchemy\Phrasea\Authentication\Phrasea\FailureManager; +use Entities\AuthFailure; +use Gedmo\Timestampable\TimestampableListener; use Symfony\Component\HttpFoundation\Request; -class FailureManagerTest extends \PHPUnit_Framework_TestCase +class FailureManagerTest extends \PhraseanetPHPUnitAbstract { /** * @covers Alchemy\Phrasea\Authentication\Phrasea\FailureManager::saveFailure @@ -241,6 +243,54 @@ class FailureManagerTest extends \PHPUnit_Framework_TestCase $manager->checkFailures($username, $request); } + public function testFailureOlderThan2MonthsAreRemovedOnFailure() + { + self::$DI['app']['EM']->getEventManager()->removeEventSubscriber(new TimestampableListener()); + $recaptcha = $this->getReCaptchaMock(null); + + $ip = '192.168.16.178'; + $username = 'romainneutron'; + + $request = $this->getRequestMock(); + $request->expects($this->any()) + ->method('getClientIp') + ->will($this->returnValue($ip)); + + for ($i = 0; $i < 10; $i++) { + $failure = new AuthFailure(); + $failure->setIp($ip); + $failure->setUsername($username); + $failure->setLocked(false); + $failure->setCreated(new \DateTime('-3 months')); + self::$DI['app']['EM']->persist($failure); + } + for ($i = 0; $i < 2; $i++) { + $failure = new AuthFailure(); + $failure->setIp($ip); + $failure->setUsername($username); + $failure->setLocked(false); + $failure->setCreated(new \DateTime('-1 months')); + self::$DI['app']['EM']->persist($failure); + } + + self::$DI['app']['EM']->flush(); + + $this->assertCount(10, self::$DI['app']['EM']->getRepository('Entities\AuthFailure') + ->findOldFailures()); + $this->assertCount(12, self::$DI['app']['EM']->getRepository('Entities\AuthFailure') + ->findAll()); + + $manager = new FailureManager(self::$DI['app']['EM'], $recaptcha, 9); + $manager->saveFailure($username, $request); + + $this->assertCount(0, self::$DI['app']['EM']->getRepository('Entities\AuthFailure') + ->findOldFailures()); + $this->assertCount(3, self::$DI['app']['EM']->getRepository('Entities\AuthFailure') + ->findAll()); + + self::$DI['app']['EM']->getEventManager()->addEventSubscriber(new TimestampableListener()); + } + private function ArrayIze($failure, $n) { $failures = array();