diff options
11 files changed, 195 insertions, 100 deletions
diff --git a/composer.json b/composer.json index 78b32307..d84e1f8b 100644 --- a/composer.json +++ b/composer.json | |||
@@ -62,7 +62,8 @@ | |||
62 | "wallabag/php-mobi": "~1.0.0", | 62 | "wallabag/php-mobi": "~1.0.0", |
63 | "kphoen/rulerz-bundle": "~0.10", | 63 | "kphoen/rulerz-bundle": "~0.10", |
64 | "guzzlehttp/guzzle": "^5.2.0", | 64 | "guzzlehttp/guzzle": "^5.2.0", |
65 | "doctrine/doctrine-migrations-bundle": "^1.0" | 65 | "doctrine/doctrine-migrations-bundle": "^1.0", |
66 | "paragonie/random_compat": "~1.0" | ||
66 | }, | 67 | }, |
67 | "require-dev": { | 68 | "require-dev": { |
68 | "doctrine/doctrine-fixtures-bundle": "~2.2", | 69 | "doctrine/doctrine-fixtures-bundle": "~2.2", |
diff --git a/src/Wallabag/CoreBundle/Command/TagAllCommand.php b/src/Wallabag/CoreBundle/Command/TagAllCommand.php index 2cf3f808..db1a9ab7 100644 --- a/src/Wallabag/CoreBundle/Command/TagAllCommand.php +++ b/src/Wallabag/CoreBundle/Command/TagAllCommand.php | |||
@@ -28,7 +28,7 @@ class TagAllCommand extends ContainerAwareCommand | |||
28 | try { | 28 | try { |
29 | $user = $this->getUser($input->getArgument('username')); | 29 | $user = $this->getUser($input->getArgument('username')); |
30 | } catch (NoResultException $e) { | 30 | } catch (NoResultException $e) { |
31 | $output->writeln(sprintf('<error>User %s not found.</error>', $input->getArgument('username'))); | 31 | $output->writeln(sprintf('<error>User "%s" not found.</error>', $input->getArgument('username'))); |
32 | 32 | ||
33 | return 1; | 33 | return 1; |
34 | } | 34 | } |
diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php index d0cf91de..6c375909 100644 --- a/src/Wallabag/CoreBundle/Controller/ConfigController.php +++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php | |||
@@ -125,7 +125,7 @@ class ConfigController extends Controller | |||
125 | $newUser->setEnabled(true); | 125 | $newUser->setEnabled(true); |
126 | $newUserForm = $this->createForm(NewUserType::class, $newUser, array( | 126 | $newUserForm = $this->createForm(NewUserType::class, $newUser, array( |
127 | 'validation_groups' => array('Profile'), | 127 | 'validation_groups' => array('Profile'), |
128 | 'action' => $this->generateUrl('config').'#set5', | 128 | 'action' => $this->generateUrl('config').'#set6', |
129 | )); | 129 | )); |
130 | $newUserForm->handleRequest($request); | 130 | $newUserForm->handleRequest($request); |
131 | 131 | ||
diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php index 9dd904f1..3e1b512f 100644 --- a/src/Wallabag/CoreBundle/Controller/EntryController.php +++ b/src/Wallabag/CoreBundle/Controller/EntryController.php | |||
@@ -54,10 +54,10 @@ class EntryController extends Controller | |||
54 | if (false !== $existingEntry) { | 54 | if (false !== $existingEntry) { |
55 | $this->get('session')->getFlashBag()->add( | 55 | $this->get('session')->getFlashBag()->add( |
56 | 'notice', | 56 | 'notice', |
57 | 'Entry already saved on '.$existingEntry['createdAt']->format('d-m-Y') | 57 | 'Entry already saved on '.$existingEntry->getCreatedAt()->format('d-m-Y') |
58 | ); | 58 | ); |
59 | 59 | ||
60 | return $this->redirect($this->generateUrl('view', array('id' => $existingEntry['id']))); | 60 | return $this->redirect($this->generateUrl('view', array('id' => $existingEntry->getId()))); |
61 | } | 61 | } |
62 | 62 | ||
63 | $this->updateEntry($entry); | 63 | $this->updateEntry($entry); |
diff --git a/src/Wallabag/CoreBundle/Tests/Command/TagAllCommandTest.php b/src/Wallabag/CoreBundle/Tests/Command/TagAllCommandTest.php new file mode 100644 index 00000000..653c1a93 --- /dev/null +++ b/src/Wallabag/CoreBundle/Tests/Command/TagAllCommandTest.php | |||
@@ -0,0 +1,60 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Tests\Command; | ||
4 | |||
5 | use Symfony\Bundle\FrameworkBundle\Console\Application; | ||
6 | use Symfony\Component\Console\Tester\CommandTester; | ||
7 | use Wallabag\CoreBundle\Command\TagAllCommand; | ||
8 | use Wallabag\CoreBundle\Tests\WallabagCoreTestCase; | ||
9 | |||
10 | class TagAllCommandTest extends WallabagCoreTestCase | ||
11 | { | ||
12 | /** | ||
13 | * @expectedException Symfony\Component\Console\Exception\RuntimeException | ||
14 | * @expectedExceptionMessage Not enough arguments (missing: "username") | ||
15 | */ | ||
16 | public function testRunTagAllCommandWithoutUsername() | ||
17 | { | ||
18 | $application = new Application($this->getClient()->getKernel()); | ||
19 | $application->add(new TagAllCommand()); | ||
20 | |||
21 | $command = $application->find('wallabag:tag:all'); | ||
22 | |||
23 | $tester = new CommandTester($command); | ||
24 | $tester->execute(array( | ||
25 | 'command' => $command->getName(), | ||
26 | )); | ||
27 | } | ||
28 | |||
29 | public function testRunTagAllCommandWithBadUsername() | ||
30 | { | ||
31 | $application = new Application($this->getClient()->getKernel()); | ||
32 | $application->add(new TagAllCommand()); | ||
33 | |||
34 | $command = $application->find('wallabag:tag:all'); | ||
35 | |||
36 | $tester = new CommandTester($command); | ||
37 | $tester->execute(array( | ||
38 | 'command' => $command->getName(), | ||
39 | 'username' => 'unknown', | ||
40 | )); | ||
41 | |||
42 | $this->assertContains('User "unknown" not found', $tester->getDisplay()); | ||
43 | } | ||
44 | |||
45 | public function testRunTagAllCommand() | ||
46 | { | ||
47 | $application = new Application($this->getClient()->getKernel()); | ||
48 | $application->add(new TagAllCommand()); | ||
49 | |||
50 | $command = $application->find('wallabag:tag:all'); | ||
51 | |||
52 | $tester = new CommandTester($command); | ||
53 | $tester->execute(array( | ||
54 | 'command' => $command->getName(), | ||
55 | 'username' => 'admin', | ||
56 | )); | ||
57 | |||
58 | $this->assertContains('Tagging entries for user « admin »... Done', $tester->getDisplay()); | ||
59 | } | ||
60 | } | ||
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php index 89ca31e2..c8807425 100644 --- a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php | |||
@@ -520,18 +520,61 @@ class ConfigControllerTest extends WallabagCoreTestCase | |||
520 | return array( | 520 | return array( |
521 | array( | 521 | array( |
522 | array( | 522 | array( |
523 | 'rss_config[rule]' => 'unknownVar <= 3', | 523 | 'tagging_rule[rule]' => 'unknownVar <= 3', |
524 | 'rss_config[tags]' => 'cool tag', | 524 | 'tagging_rule[tags]' => 'cool tag', |
525 | ), | ||
526 | array( | ||
527 | 'The variable', | ||
528 | 'does not exist.', | ||
525 | ), | 529 | ), |
526 | 'The variable « unknownVar » does not exist.', | ||
527 | ), | 530 | ), |
528 | array( | 531 | array( |
529 | array( | 532 | array( |
530 | 'rss_config[rule]' => 'length(domainName) <= 42', | 533 | 'tagging_rule[rule]' => 'length(domainName) <= 42', |
531 | 'rss_config[tags]' => 'cool tag', | 534 | 'tagging_rule[tags]' => 'cool tag', |
535 | ), | ||
536 | array( | ||
537 | 'The operator', | ||
538 | 'does not exist.', | ||
532 | ), | 539 | ), |
533 | 'The operator « length » does not exist.', | ||
534 | ), | 540 | ), |
535 | ); | 541 | ); |
536 | } | 542 | } |
543 | |||
544 | /** | ||
545 | * @dataProvider dataForTaggingRuleFailed | ||
546 | */ | ||
547 | public function testTaggingRuleCreationFail($data, $messages) | ||
548 | { | ||
549 | $this->logInAs('admin'); | ||
550 | $client = $this->getClient(); | ||
551 | |||
552 | $crawler = $client->request('GET', '/config'); | ||
553 | |||
554 | $this->assertTrue($client->getResponse()->isSuccessful()); | ||
555 | |||
556 | $form = $crawler->filter('button[id=tagging_rule_save]')->form(); | ||
557 | |||
558 | $client->submit($form, $data); | ||
559 | |||
560 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
561 | |||
562 | foreach ($messages as $message) { | ||
563 | $this->assertContains($message, $client->getResponse()->getContent()); | ||
564 | } | ||
565 | } | ||
566 | |||
567 | public function testDeletingTaggingRuleFromAnOtherUser() | ||
568 | { | ||
569 | $this->logInAs('bob'); | ||
570 | $client = $this->getClient(); | ||
571 | |||
572 | $rule = $client->getContainer()->get('doctrine.orm.entity_manager') | ||
573 | ->getRepository('WallabagCoreBundle:TaggingRule') | ||
574 | ->findAll()[0]; | ||
575 | |||
576 | $client->request('GET', '/tagging-rule/delete/'.$rule->getId()); | ||
577 | $this->assertEquals(403, $client->getResponse()->getStatusCode()); | ||
578 | $this->assertContains('You can not access this tagging ryle', $client->getResponse()->getContent()); | ||
579 | } | ||
537 | } | 580 | } |
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php index 1d1620dc..32d6a575 100644 --- a/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php | |||
@@ -127,10 +127,35 @@ class EntryControllerTest extends WallabagCoreTestCase | |||
127 | 127 | ||
128 | $this->assertEquals(302, $client->getResponse()->getStatusCode()); | 128 | $this->assertEquals(302, $client->getResponse()->getStatusCode()); |
129 | 129 | ||
130 | $crawler = $client->followRedirect(); | 130 | $content = $client->getContainer() |
131 | ->get('doctrine.orm.entity_manager') | ||
132 | ->getRepository('WallabagCoreBundle:Entry') | ||
133 | ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); | ||
134 | |||
135 | $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); | ||
136 | $this->assertEquals($this->url, $content->getUrl()); | ||
137 | $this->assertContains('Google', $content->getTitle()); | ||
138 | } | ||
139 | |||
140 | public function testPostNewOkUrlExist() | ||
141 | { | ||
142 | $this->logInAs('admin'); | ||
143 | $client = $this->getClient(); | ||
144 | |||
145 | $crawler = $client->request('GET', '/new'); | ||
146 | |||
147 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); | ||
148 | |||
149 | $form = $crawler->filter('button[type=submit]')->form(); | ||
150 | |||
151 | $data = array( | ||
152 | 'entry[url]' => $this->url, | ||
153 | ); | ||
131 | 154 | ||
132 | $this->assertGreaterThan(1, $alert = $crawler->filter('h2 a')->extract(array('_text'))); | 155 | $client->submit($form, $data); |
133 | $this->assertContains('Google', $alert[0]); | 156 | |
157 | $this->assertEquals(302, $client->getResponse()->getStatusCode()); | ||
158 | $this->assertContains('/view/', $client->getResponse()->getTargetUrl()); | ||
134 | } | 159 | } |
135 | 160 | ||
136 | /** | 161 | /** |
diff --git a/src/Wallabag/CoreBundle/Tools/Utils.php b/src/Wallabag/CoreBundle/Tools/Utils.php index a16baca9..0c783110 100644 --- a/src/Wallabag/CoreBundle/Tools/Utils.php +++ b/src/Wallabag/CoreBundle/Tools/Utils.php | |||
@@ -7,20 +7,13 @@ class Utils | |||
7 | /** | 7 | /** |
8 | * Generate a token used for RSS. | 8 | * Generate a token used for RSS. |
9 | * | 9 | * |
10 | * @param int $length Length of the token | ||
11 | * | ||
10 | * @return string | 12 | * @return string |
11 | */ | 13 | */ |
12 | public static function generateToken() | 14 | public static function generateToken($length = 15) |
13 | { | 15 | { |
14 | if (ini_get('open_basedir') === '') { | 16 | $token = substr(base64_encode(random_bytes($length)), 0, $length); |
15 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { | ||
16 | // alternative to /dev/urandom for Windows | ||
17 | $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20); | ||
18 | } else { | ||
19 | $token = substr(base64_encode(file_get_contents('/dev/urandom', false, null, 0, 20)), 0, 15); | ||
20 | } | ||
21 | } else { | ||
22 | $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20); | ||
23 | } | ||
24 | 17 | ||
25 | // remove character which can broken the url | 18 | // remove character which can broken the url |
26 | return str_replace(array('+', '/'), '', $token); | 19 | return str_replace(array('+', '/'), '', $token); |
diff --git a/src/Wallabag/UserBundle/Controller/ResettingController.php b/src/Wallabag/UserBundle/Controller/ResettingController.php deleted file mode 100644 index 62e27d00..00000000 --- a/src/Wallabag/UserBundle/Controller/ResettingController.php +++ /dev/null | |||
@@ -1,75 +0,0 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\UserBundle\Controller; | ||
4 | |||
5 | use FOS\UserBundle\Event\FilterUserResponseEvent; | ||
6 | use FOS\UserBundle\Event\FormEvent; | ||
7 | use FOS\UserBundle\Event\GetResponseUserEvent; | ||
8 | use FOS\UserBundle\FOSUserEvents; | ||
9 | use Symfony\Component\HttpFoundation\RedirectResponse; | ||
10 | use Symfony\Component\HttpFoundation\Request; | ||
11 | use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | ||
12 | |||
13 | class ResettingController extends \FOS\UserBundle\Controller\ResettingController | ||
14 | { | ||
15 | /** | ||
16 | * Extends ResettingController to change the redirection after success. | ||
17 | * | ||
18 | * @param Request $request | ||
19 | * @param $token | ||
20 | * | ||
21 | * @return null|RedirectResponse|\Symfony\Component\HttpFoundation\Response | ||
22 | */ | ||
23 | public function resetAction(Request $request, $token) | ||
24 | { | ||
25 | /** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */ | ||
26 | $formFactory = $this->get('fos_user.resetting.form.factory'); | ||
27 | /** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */ | ||
28 | $userManager = $this->get('fos_user.user_manager'); | ||
29 | /** @var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */ | ||
30 | $dispatcher = $this->get('event_dispatcher'); | ||
31 | |||
32 | $user = $userManager->findUserByConfirmationToken($token); | ||
33 | |||
34 | if (null === $user) { | ||
35 | throw new NotFoundHttpException(sprintf('The user with "confirmation token" does not exist for value "%s"', $token)); | ||
36 | } | ||
37 | |||
38 | $event = new GetResponseUserEvent($user, $request); | ||
39 | $dispatcher->dispatch(FOSUserEvents::RESETTING_RESET_INITIALIZE, $event); | ||
40 | |||
41 | if (null !== $event->getResponse()) { | ||
42 | return $event->getResponse(); | ||
43 | } | ||
44 | |||
45 | $form = $formFactory->createForm(); | ||
46 | $form->setData($user); | ||
47 | |||
48 | $form->handleRequest($request); | ||
49 | |||
50 | if ($form->isValid()) { | ||
51 | $event = new FormEvent($form, $request); | ||
52 | $dispatcher->dispatch(FOSUserEvents::RESETTING_RESET_SUCCESS, $event); | ||
53 | |||
54 | $userManager->updateUser($user); | ||
55 | |||
56 | if (null === $response = $event->getResponse()) { | ||
57 | $this->get('session')->getFlashBag()->add( | ||
58 | 'notice', | ||
59 | 'Password updated' | ||
60 | ); | ||
61 | $url = $this->generateUrl('homepage'); | ||
62 | $response = new RedirectResponse($url); | ||
63 | } | ||
64 | |||
65 | $dispatcher->dispatch(FOSUserEvents::RESETTING_RESET_COMPLETED, new FilterUserResponseEvent($user, $request, $response)); | ||
66 | |||
67 | return $response; | ||
68 | } | ||
69 | |||
70 | return $this->render('FOSUserBundle:Resetting:reset.html.twig', array( | ||
71 | 'token' => $token, | ||
72 | 'form' => $form->createView(), | ||
73 | )); | ||
74 | } | ||
75 | } | ||
diff --git a/src/Wallabag/UserBundle/EventListener/PasswordResettingListener.php b/src/Wallabag/UserBundle/EventListener/PasswordResettingListener.php new file mode 100644 index 00000000..128e85a4 --- /dev/null +++ b/src/Wallabag/UserBundle/EventListener/PasswordResettingListener.php | |||
@@ -0,0 +1,41 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\UserBundle\EventListener; | ||
4 | |||
5 | use FOS\UserBundle\FOSUserEvents; | ||
6 | use FOS\UserBundle\Event\FormEvent; | ||
7 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; | ||
8 | use Symfony\Component\HttpFoundation\RedirectResponse; | ||
9 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | ||
10 | |||
11 | /** | ||
12 | * Listener responsible to change the redirection at the end of the password resetting. | ||
13 | * | ||
14 | * @see http://symfony.com/doc/current/bundles/FOSUserBundle/controller_events.html | ||
15 | */ | ||
16 | class PasswordResettingListener implements EventSubscriberInterface | ||
17 | { | ||
18 | private $router; | ||
19 | |||
20 | public function __construct(UrlGeneratorInterface $router) | ||
21 | { | ||
22 | $this->router = $router; | ||
23 | } | ||
24 | |||
25 | /** | ||
26 | * {@inheritdoc} | ||
27 | */ | ||
28 | public static function getSubscribedEvents() | ||
29 | { | ||
30 | return array( | ||
31 | FOSUserEvents::RESETTING_RESET_SUCCESS => 'onPasswordResettingSuccess', | ||
32 | ); | ||
33 | } | ||
34 | |||
35 | public function onPasswordResettingSuccess(FormEvent $event) | ||
36 | { | ||
37 | $url = $this->router->generate('homepage'); | ||
38 | |||
39 | $event->setResponse(new RedirectResponse($url)); | ||
40 | } | ||
41 | } | ||
diff --git a/src/Wallabag/UserBundle/Resources/config/services.yml b/src/Wallabag/UserBundle/Resources/config/services.yml index 93e04d59..bf9e036a 100644 --- a/src/Wallabag/UserBundle/Resources/config/services.yml +++ b/src/Wallabag/UserBundle/Resources/config/services.yml | |||
@@ -8,3 +8,10 @@ services: | |||
8 | - "%scheb_two_factor.email.sender_name%" | 8 | - "%scheb_two_factor.email.sender_name%" |
9 | - "%wallabag_support_url%" | 9 | - "%wallabag_support_url%" |
10 | - "%wallabag_url%" | 10 | - "%wallabag_url%" |
11 | |||
12 | wallabag_user.password_resetting: | ||
13 | class: Wallabag\UserBundle\EventListener\PasswordResettingListener | ||
14 | arguments: | ||
15 | - "@router" | ||
16 | tags: | ||
17 | - { name: kernel.event_subscriber } | ||