From 115de64e5bb9d7f9151ecf15e15a0d988563528e Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Thu, 4 Oct 2018 14:07:20 +0200 Subject: Jump to Symfony 3.4 Thanks to the BC compatibility, almost nothing have to be changed. All changes are related to new bundle version of: - SensioFrameworkExtraBundle - DoctrineFixturesBundle --- src/Wallabag/UserBundle/Controller/ManageController.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src/Wallabag/UserBundle') diff --git a/src/Wallabag/UserBundle/Controller/ManageController.php b/src/Wallabag/UserBundle/Controller/ManageController.php index f3de656f..a9746fb4 100644 --- a/src/Wallabag/UserBundle/Controller/ManageController.php +++ b/src/Wallabag/UserBundle/Controller/ManageController.php @@ -7,10 +7,9 @@ use FOS\UserBundle\FOSUserEvents; use Pagerfanta\Adapter\DoctrineORMAdapter; use Pagerfanta\Exception\OutOfRangeCurrentPageException; use Pagerfanta\Pagerfanta; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Routing\Annotation\Route; use Wallabag\UserBundle\Entity\User; use Wallabag\UserBundle\Form\SearchUserType; @@ -22,8 +21,7 @@ class ManageController extends Controller /** * Creates a new User entity. * - * @Route("/new", name="user_new") - * @Method({"GET", "POST"}) + * @Route("/new", name="user_new", methods={"GET", "POST"}) */ public function newAction(Request $request) { @@ -60,8 +58,7 @@ class ManageController extends Controller /** * Displays a form to edit an existing User entity. * - * @Route("/{id}/edit", name="user_edit") - * @Method({"GET", "POST"}) + * @Route("/{id}/edit", name="user_edit", methods={"GET", "POST"}) */ public function editAction(Request $request, User $user) { @@ -93,8 +90,7 @@ class ManageController extends Controller /** * Deletes a User entity. * - * @Route("/{id}", name="user_delete") - * @Method("DELETE") + * @Route("/{id}", name="user_delete", methods={"DELETE"}) */ public function deleteAction(Request $request, User $user) { -- cgit v1.2.3 From be417ef23685e17a239b1d192a0e9b9f484f1bfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Mon, 12 Jun 2017 17:23:35 +0200 Subject: Added possibility to change locale from login/register pages --- src/Wallabag/UserBundle/EventListener/CreateConfigListener.php | 7 +++++-- src/Wallabag/UserBundle/Resources/config/services.yml | 1 + .../Resources/views/Registration/register_content.html.twig | 1 - src/Wallabag/UserBundle/Resources/views/layout.html.twig | 5 +++++ 4 files changed, 11 insertions(+), 3 deletions(-) (limited to 'src/Wallabag/UserBundle') diff --git a/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php b/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php index e4d55c19..5cabfd35 100644 --- a/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php +++ b/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php @@ -6,6 +6,7 @@ use Doctrine\ORM\EntityManager; use FOS\UserBundle\Event\UserEvent; use FOS\UserBundle\FOSUserEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\Session\Session; use Wallabag\CoreBundle\Entity\Config; /** @@ -22,8 +23,9 @@ class CreateConfigListener implements EventSubscriberInterface private $readingSpeed; private $actionMarkAsRead; private $listMode; + private $session; - public function __construct(EntityManager $em, $theme, $itemsOnPage, $rssLimit, $language, $readingSpeed, $actionMarkAsRead, $listMode) + public function __construct(EntityManager $em, $theme, $itemsOnPage, $rssLimit, $language, $readingSpeed, $actionMarkAsRead, $listMode, Session $session) { $this->em = $em; $this->theme = $theme; @@ -33,6 +35,7 @@ class CreateConfigListener implements EventSubscriberInterface $this->readingSpeed = $readingSpeed; $this->actionMarkAsRead = $actionMarkAsRead; $this->listMode = $listMode; + $this->session = $session; } public static function getSubscribedEvents() @@ -52,7 +55,7 @@ class CreateConfigListener implements EventSubscriberInterface $config->setTheme($this->theme); $config->setItemsPerPage($this->itemsOnPage); $config->setRssLimit($this->rssLimit); - $config->setLanguage($this->language); + $config->setLanguage($this->session->get('_locale', $this->language)); $config->setReadingSpeed($this->readingSpeed); $config->setActionMarkAsRead($this->actionMarkAsRead); $config->setListMode($this->listMode); diff --git a/src/Wallabag/UserBundle/Resources/config/services.yml b/src/Wallabag/UserBundle/Resources/config/services.yml index d3925de3..72cda3f8 100644 --- a/src/Wallabag/UserBundle/Resources/config/services.yml +++ b/src/Wallabag/UserBundle/Resources/config/services.yml @@ -33,6 +33,7 @@ services: - "%wallabag_core.reading_speed%" - "%wallabag_core.action_mark_as_read%" - "%wallabag_core.list_mode%" + - "@session" tags: - { name: kernel.event_subscriber } diff --git a/src/Wallabag/UserBundle/Resources/views/Registration/register_content.html.twig b/src/Wallabag/UserBundle/Resources/views/Registration/register_content.html.twig index d0a85fc7..85cd4f0d 100644 --- a/src/Wallabag/UserBundle/Resources/views/Registration/register_content.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Registration/register_content.html.twig @@ -3,7 +3,6 @@ {{ form_start(form, {'method': 'post', 'action': path('fos_user_registration_register'), 'attr': {'class': 'fos_user_registration_register'}}) }}
- {{ form_widget(form._token) }} {% for flashMessage in app.session.flashbag.get('notice') %} diff --git a/src/Wallabag/UserBundle/Resources/views/layout.html.twig b/src/Wallabag/UserBundle/Resources/views/layout.html.twig index 99bf7dfd..6934c686 100644 --- a/src/Wallabag/UserBundle/Resources/views/layout.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/layout.html.twig @@ -15,6 +15,11 @@ {% block fos_user_content %} {% endblock fos_user_content %}
+
{% endblock %} -- cgit v1.2.3 From 4d4147b228ac90f329fd2d40dd4fb60cb980328a Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Sat, 13 Oct 2018 09:24:39 +0200 Subject: Ensure language is valid - Do not override locale if user has choosen a locale from the login screen. - Add some tests about locale url --- src/Wallabag/UserBundle/Resources/views/layout.html.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/Wallabag/UserBundle') diff --git a/src/Wallabag/UserBundle/Resources/views/layout.html.twig b/src/Wallabag/UserBundle/Resources/views/layout.html.twig index 6934c686..b53f8746 100644 --- a/src/Wallabag/UserBundle/Resources/views/layout.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/layout.html.twig @@ -16,8 +16,8 @@ {% endblock fos_user_content %} -- cgit v1.2.3 From db9b6d8d0d9f943fe321ea690701662dac828e94 Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Mon, 26 Nov 2018 20:00:01 +0100 Subject: Update fixtures --- .../UserBundle/DataFixtures/ORM/LoadUserData.php | 61 ---------------------- .../UserBundle/DataFixtures/UserFixtures.php | 52 ++++++++++++++++++ 2 files changed, 52 insertions(+), 61 deletions(-) delete mode 100644 src/Wallabag/UserBundle/DataFixtures/ORM/LoadUserData.php create mode 100644 src/Wallabag/UserBundle/DataFixtures/UserFixtures.php (limited to 'src/Wallabag/UserBundle') diff --git a/src/Wallabag/UserBundle/DataFixtures/ORM/LoadUserData.php b/src/Wallabag/UserBundle/DataFixtures/ORM/LoadUserData.php deleted file mode 100644 index 26dbda3b..00000000 --- a/src/Wallabag/UserBundle/DataFixtures/ORM/LoadUserData.php +++ /dev/null @@ -1,61 +0,0 @@ -setName('Big boss'); - $userAdmin->setEmail('bigboss@wallabag.org'); - $userAdmin->setUsername('admin'); - $userAdmin->setPlainPassword('mypassword'); - $userAdmin->setEnabled(true); - $userAdmin->addRole('ROLE_SUPER_ADMIN'); - - $manager->persist($userAdmin); - - $this->addReference('admin-user', $userAdmin); - - $bobUser = new User(); - $bobUser->setName('Bobby'); - $bobUser->setEmail('bobby@wallabag.org'); - $bobUser->setUsername('bob'); - $bobUser->setPlainPassword('mypassword'); - $bobUser->setEnabled(true); - - $manager->persist($bobUser); - - $this->addReference('bob-user', $bobUser); - - $emptyUser = new User(); - $emptyUser->setName('Empty'); - $emptyUser->setEmail('empty@wallabag.org'); - $emptyUser->setUsername('empty'); - $emptyUser->setPlainPassword('mypassword'); - $emptyUser->setEnabled(true); - - $manager->persist($emptyUser); - - $this->addReference('empty-user', $emptyUser); - - $manager->flush(); - } - - /** - * {@inheritdoc} - */ - public function getOrder() - { - return 10; - } -} diff --git a/src/Wallabag/UserBundle/DataFixtures/UserFixtures.php b/src/Wallabag/UserBundle/DataFixtures/UserFixtures.php new file mode 100644 index 00000000..1e375e09 --- /dev/null +++ b/src/Wallabag/UserBundle/DataFixtures/UserFixtures.php @@ -0,0 +1,52 @@ +setName('Big boss'); + $userAdmin->setEmail('bigboss@wallabag.org'); + $userAdmin->setUsername('admin'); + $userAdmin->setPlainPassword('mypassword'); + $userAdmin->setEnabled(true); + $userAdmin->addRole('ROLE_SUPER_ADMIN'); + + $manager->persist($userAdmin); + + $this->addReference('admin-user', $userAdmin); + + $bobUser = new User(); + $bobUser->setName('Bobby'); + $bobUser->setEmail('bobby@wallabag.org'); + $bobUser->setUsername('bob'); + $bobUser->setPlainPassword('mypassword'); + $bobUser->setEnabled(true); + + $manager->persist($bobUser); + + $this->addReference('bob-user', $bobUser); + + $emptyUser = new User(); + $emptyUser->setName('Empty'); + $emptyUser->setEmail('empty@wallabag.org'); + $emptyUser->setUsername('empty'); + $emptyUser->setPlainPassword('mypassword'); + $emptyUser->setEnabled(true); + + $manager->persist($emptyUser); + + $this->addReference('empty-user', $emptyUser); + + $manager->flush(); + } +} -- cgit v1.2.3 From a6b242a1fd6f8900d80354361449f1bf62506ef9 Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Sun, 2 Dec 2018 12:43:05 +0100 Subject: Enable OTP 2FA - Update SchebTwoFactorBundle to version 3 - Enable Google 2fa on the bundle - Disallow ability to use both email and google as 2fa - Update Ocramius Proxy Manager to handle typed function & attributes (from PHP 7) - use `$this->addFlash` shortcut instead of `$this->get('session')->getFlashBag()->add` - update admin to be able to create/reset the 2fa --- .../UserBundle/Controller/ManageController.php | 67 ++++++++++++--- src/Wallabag/UserBundle/Entity/User.php | 94 +++++++++++++++------- src/Wallabag/UserBundle/Form/UserType.php | 9 ++- src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php | 2 +- .../Resources/views/Authentication/form.html.twig | 14 +++- .../Resources/views/Manage/edit.html.twig | 17 +++- 6 files changed, 156 insertions(+), 47 deletions(-) (limited to 'src/Wallabag/UserBundle') diff --git a/src/Wallabag/UserBundle/Controller/ManageController.php b/src/Wallabag/UserBundle/Controller/ManageController.php index a9746fb4..08ed25dd 100644 --- a/src/Wallabag/UserBundle/Controller/ManageController.php +++ b/src/Wallabag/UserBundle/Controller/ManageController.php @@ -8,6 +8,7 @@ use Pagerfanta\Adapter\DoctrineORMAdapter; use Pagerfanta\Exception\OutOfRangeCurrentPageException; use Pagerfanta\Pagerfanta; use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; use Wallabag\UserBundle\Entity\User; @@ -31,10 +32,10 @@ class ManageController extends Controller // enable created user by default $user->setEnabled(true); - $form = $this->createForm('Wallabag\UserBundle\Form\NewUserType', $user); - $form->handleRequest($request); + $form = $this->createEditForm('NewUserType', $user, $request); if ($form->isSubmitted() && $form->isValid()) { + $user = $this->handleOtp($form, $user); $userManager->updateUser($user); // dispatch a created event so the associated config will be created @@ -62,14 +63,14 @@ class ManageController extends Controller */ public function editAction(Request $request, User $user) { + $userManager = $this->container->get('fos_user.user_manager'); + $deleteForm = $this->createDeleteForm($user); - $editForm = $this->createForm('Wallabag\UserBundle\Form\UserType', $user); - $editForm->handleRequest($request); + $form = $this->createEditForm('UserType', $user, $request); - if ($editForm->isSubmitted() && $editForm->isValid()) { - $em = $this->getDoctrine()->getManager(); - $em->persist($user); - $em->flush(); + if ($form->isSubmitted() && $form->isValid()) { + $user = $this->handleOtp($form, $user); + $userManager->updateUser($user); $this->get('session')->getFlashBag()->add( 'notice', @@ -81,7 +82,7 @@ class ManageController extends Controller return $this->render('WallabagUserBundle:Manage:edit.html.twig', [ 'user' => $user, - 'edit_form' => $editForm->createView(), + 'edit_form' => $form->createView(), 'delete_form' => $deleteForm->createView(), 'twofactor_auth' => $this->getParameter('twofactor_auth'), ]); @@ -157,7 +158,7 @@ class ManageController extends Controller } /** - * Creates a form to delete a User entity. + * Create a form to delete a User entity. * * @param User $user The User entity * @@ -171,4 +172,50 @@ class ManageController extends Controller ->getForm() ; } + + /** + * Create a form to create or edit a User entity. + * + * @param string $type Might be NewUserType or UserType + * @param User $user The new / edit user + * @param Request $request The request + * + * @return FormInterface + */ + private function createEditForm($type, User $user, Request $request) + { + $form = $this->createForm('Wallabag\UserBundle\Form\\' . $type, $user); + $form->handleRequest($request); + + // `googleTwoFactor` isn't a field within the User entity, we need to define it's value in a different way + if (true === $user->isGoogleAuthenticatorEnabled() && false === $form->isSubmitted()) { + $form->get('googleTwoFactor')->setData(true); + } + + return $form; + } + + /** + * Handle OTP update, taking care to only have one 2fa enable at a time. + * + * @see ConfigController + * + * @param FormInterface $form + * @param User $user + * + * @return User + */ + private function handleOtp(FormInterface $form, User $user) + { + if (true === $form->get('googleTwoFactor')->getData() && false === $user->isGoogleAuthenticatorEnabled()) { + $user->setGoogleAuthenticatorSecret($this->get('scheb_two_factor.security.google_authenticator')->generateSecret()); + $user->setEmailTwoFactor(false); + + return $user; + } + + $user->setGoogleAuthenticatorSecret(null); + + return $user; + } } diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php index 48446e3c..6e305719 100644 --- a/src/Wallabag/UserBundle/Entity/User.php +++ b/src/Wallabag/UserBundle/Entity/User.php @@ -8,8 +8,8 @@ use FOS\UserBundle\Model\User as BaseUser; use JMS\Serializer\Annotation\Accessor; use JMS\Serializer\Annotation\Groups; use JMS\Serializer\Annotation\XmlRoot; -use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface; -use Scheb\TwoFactorBundle\Model\TrustedComputerInterface; +use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface as EmailTwoFactorInterface; +use Scheb\TwoFactorBundle\Model\Google\TwoFactorInterface as GoogleTwoFactorInterface; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Security\Core\User\UserInterface; use Wallabag\ApiBundle\Entity\Client; @@ -28,7 +28,7 @@ use Wallabag\CoreBundle\Helper\EntityTimestampsTrait; * @UniqueEntity("email") * @UniqueEntity("username") */ -class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterface +class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorInterface { use EntityTimestampsTrait; @@ -123,16 +123,16 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf private $authCode; /** - * @var bool - * - * @ORM\Column(type="boolean") + * @ORM\Column(name="googleAuthenticatorSecret", type="string", nullable=true) */ - private $twoFactorAuthentication = false; + private $googleAuthenticatorSecret; /** - * @ORM\Column(type="json_array", nullable=true) + * @var bool + * + * @ORM\Column(type="boolean") */ - private $trusted; + private $emailTwoFactor = false; public function __construct() { @@ -233,49 +233,89 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf /** * @return bool */ - public function isTwoFactorAuthentication() + public function isEmailTwoFactor() + { + return $this->emailTwoFactor; + } + + /** + * @param bool $emailTwoFactor + */ + public function setEmailTwoFactor($emailTwoFactor) { - return $this->twoFactorAuthentication; + $this->emailTwoFactor = $emailTwoFactor; } /** - * @param bool $twoFactorAuthentication + * Used in the user config form to be "like" the email option. */ - public function setTwoFactorAuthentication($twoFactorAuthentication) + public function isGoogleTwoFactor() { - $this->twoFactorAuthentication = $twoFactorAuthentication; + return $this->isGoogleAuthenticatorEnabled(); } - public function isEmailAuthEnabled() + /** + * {@inheritdoc} + */ + public function isEmailAuthEnabled(): bool { - return $this->twoFactorAuthentication; + return $this->emailTwoFactor; } - public function getEmailAuthCode() + /** + * {@inheritdoc} + */ + public function getEmailAuthCode(): string { return $this->authCode; } - public function setEmailAuthCode($authCode) + /** + * {@inheritdoc} + */ + public function setEmailAuthCode(string $authCode): void { $this->authCode = $authCode; } - public function addTrustedComputer($token, \DateTime $validUntil) + /** + * {@inheritdoc} + */ + public function getEmailAuthRecipient(): string { - $this->trusted[$token] = $validUntil->format('r'); + return $this->email; } - public function isTrustedComputer($token) + /** + * {@inheritdoc} + */ + public function isGoogleAuthenticatorEnabled(): bool { - if (isset($this->trusted[$token])) { - $now = new \DateTime(); - $validUntil = new \DateTime($this->trusted[$token]); + return $this->googleAuthenticatorSecret ? true : false; + } - return $now < $validUntil; - } + /** + * {@inheritdoc} + */ + public function getGoogleAuthenticatorUsername(): string + { + return $this->username; + } - return false; + /** + * {@inheritdoc} + */ + public function getGoogleAuthenticatorSecret(): string + { + return $this->googleAuthenticatorSecret; + } + + /** + * {@inheritdoc} + */ + public function setGoogleAuthenticatorSecret(?string $googleAuthenticatorSecret): void + { + $this->googleAuthenticatorSecret = $googleAuthenticatorSecret; } /** diff --git a/src/Wallabag/UserBundle/Form/UserType.php b/src/Wallabag/UserBundle/Form/UserType.php index 56fea640..026db9a2 100644 --- a/src/Wallabag/UserBundle/Form/UserType.php +++ b/src/Wallabag/UserBundle/Form/UserType.php @@ -35,9 +35,14 @@ class UserType extends AbstractType 'required' => false, 'label' => 'user.form.enabled_label', ]) - ->add('twoFactorAuthentication', CheckboxType::class, [ + ->add('emailTwoFactor', CheckboxType::class, [ 'required' => false, - 'label' => 'user.form.twofactor_label', + 'label' => 'user.form.twofactor_email_label', + ]) + ->add('googleTwoFactor', CheckboxType::class, [ + 'required' => false, + 'label' => 'user.form.twofactor_google_label', + 'mapped' => false, ]) ->add('save', SubmitType::class, [ 'label' => 'user.form.save', diff --git a/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php b/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php index aed805c9..e8e29aa9 100644 --- a/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php +++ b/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php @@ -78,7 +78,7 @@ class AuthCodeMailer implements AuthCodeMailerInterface * * @param TwoFactorInterface $user */ - public function sendAuthCode(TwoFactorInterface $user) + public function sendAuthCode(TwoFactorInterface $user): void { $template = $this->twig->loadTemplate('WallabagUserBundle:TwoFactor:email_auth_code.html.twig'); diff --git a/src/Wallabag/UserBundle/Resources/views/Authentication/form.html.twig b/src/Wallabag/UserBundle/Resources/views/Authentication/form.html.twig index c8471bdd..47a5cb78 100644 --- a/src/Wallabag/UserBundle/Resources/views/Authentication/form.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Authentication/form.html.twig @@ -1,7 +1,8 @@ +{# Override `vendor/scheb/two-factor-bundle/Resources/views/Authentication/form.html.twig` #} {% extends "WallabagUserBundle::layout.html.twig" %} {% block fos_user_content %} -
+
@@ -9,14 +10,19 @@

{{ flashMessage|trans }}

{% endfor %} + {# Authentication errors #} + {% if authenticationError %} +

{{ authenticationError|trans(authenticationErrorData) }}

+ {% endif %} +
- +
- {% if useTrustedOption %} + {% if displayTrustedOption %}
- +
{% endif %} diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig index 3ffd15f5..8be37e79 100644 --- a/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig @@ -50,10 +50,21 @@ {% if twofactor_auth %}
- {{ form_widget(edit_form.twoFactorAuthentication) }} - {{ form_label(edit_form.twoFactorAuthentication) }} - {{ form_errors(edit_form.twoFactorAuthentication) }} + {{ form_widget(edit_form.emailTwoFactor) }} + {{ form_label(edit_form.emailTwoFactor) }} + {{ form_errors(edit_form.emailTwoFactor) }}
+
+ {{ form_widget(edit_form.googleTwoFactor) }} + {{ form_label(edit_form.googleTwoFactor) }} + {{ form_errors(edit_form.googleTwoFactor) }} +
+ + {% if user.isGoogleAuthenticatorEnabled %} +
+

OTP Secret: {{ user.googleAuthenticatorSecret }}

+
+ {% endif %}
{% endif %} -- cgit v1.2.3 From 2dfbe9e5faf40364b60e6c76f3cc9fac5bf11fa4 Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Sun, 2 Dec 2018 18:39:02 +0100 Subject: Fix tests --- .../UserBundle/Controller/ManageController.php | 70 ++++++---------------- 1 file changed, 19 insertions(+), 51 deletions(-) (limited to 'src/Wallabag/UserBundle') diff --git a/src/Wallabag/UserBundle/Controller/ManageController.php b/src/Wallabag/UserBundle/Controller/ManageController.php index 08ed25dd..b9fd8660 100644 --- a/src/Wallabag/UserBundle/Controller/ManageController.php +++ b/src/Wallabag/UserBundle/Controller/ManageController.php @@ -8,7 +8,6 @@ use Pagerfanta\Adapter\DoctrineORMAdapter; use Pagerfanta\Exception\OutOfRangeCurrentPageException; use Pagerfanta\Pagerfanta; use Symfony\Bundle\FrameworkBundle\Controller\Controller; -use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; use Wallabag\UserBundle\Entity\User; @@ -32,10 +31,10 @@ class ManageController extends Controller // enable created user by default $user->setEnabled(true); - $form = $this->createEditForm('NewUserType', $user, $request); + $form = $this->createForm('Wallabag\UserBundle\Form\NewUserType', $user); + $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $user = $this->handleOtp($form, $user); $userManager->updateUser($user); // dispatch a created event so the associated config will be created @@ -66,10 +65,25 @@ class ManageController extends Controller $userManager = $this->container->get('fos_user.user_manager'); $deleteForm = $this->createDeleteForm($user); - $form = $this->createEditForm('UserType', $user, $request); + $form = $this->createForm('Wallabag\UserBundle\Form\UserType', $user); + $form->handleRequest($request); + + // `googleTwoFactor` isn't a field within the User entity, we need to define it's value in a different way + if ($this->getParameter('twofactor_auth') && true === $user->isGoogleAuthenticatorEnabled() && false === $form->isSubmitted()) { + $form->get('googleTwoFactor')->setData(true); + } if ($form->isSubmitted() && $form->isValid()) { - $user = $this->handleOtp($form, $user); + // handle creation / reset of the OTP secret if checkbox changed from the previous state + if ($this->getParameter('twofactor_auth')) { + if (true === $form->get('googleTwoFactor')->getData() && false === $user->isGoogleAuthenticatorEnabled()) { + $user->setGoogleAuthenticatorSecret($this->get('scheb_two_factor.security.google_authenticator')->generateSecret()); + $user->setEmailTwoFactor(false); + } elseif (false === $form->get('googleTwoFactor')->getData() && true === $user->isGoogleAuthenticatorEnabled()) { + $user->setGoogleAuthenticatorSecret(null); + } + } + $userManager->updateUser($user); $this->get('session')->getFlashBag()->add( @@ -172,50 +186,4 @@ class ManageController extends Controller ->getForm() ; } - - /** - * Create a form to create or edit a User entity. - * - * @param string $type Might be NewUserType or UserType - * @param User $user The new / edit user - * @param Request $request The request - * - * @return FormInterface - */ - private function createEditForm($type, User $user, Request $request) - { - $form = $this->createForm('Wallabag\UserBundle\Form\\' . $type, $user); - $form->handleRequest($request); - - // `googleTwoFactor` isn't a field within the User entity, we need to define it's value in a different way - if (true === $user->isGoogleAuthenticatorEnabled() && false === $form->isSubmitted()) { - $form->get('googleTwoFactor')->setData(true); - } - - return $form; - } - - /** - * Handle OTP update, taking care to only have one 2fa enable at a time. - * - * @see ConfigController - * - * @param FormInterface $form - * @param User $user - * - * @return User - */ - private function handleOtp(FormInterface $form, User $user) - { - if (true === $form->get('googleTwoFactor')->getData() && false === $user->isGoogleAuthenticatorEnabled()) { - $user->setGoogleAuthenticatorSecret($this->get('scheb_two_factor.security.google_authenticator')->generateSecret()); - $user->setEmailTwoFactor(false); - - return $user; - } - - $user->setGoogleAuthenticatorSecret(null); - - return $user; - } } -- cgit v1.2.3 From 43ccf4b1787c294dbfa7b052c41e95ac9eeca3af Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Sun, 2 Dec 2018 18:47:34 +0100 Subject: Cleanup --- src/Wallabag/UserBundle/Controller/ManageController.php | 2 -- src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src/Wallabag/UserBundle') diff --git a/src/Wallabag/UserBundle/Controller/ManageController.php b/src/Wallabag/UserBundle/Controller/ManageController.php index b9fd8660..63a06206 100644 --- a/src/Wallabag/UserBundle/Controller/ManageController.php +++ b/src/Wallabag/UserBundle/Controller/ManageController.php @@ -146,8 +146,6 @@ class ManageController extends Controller $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $this->get('logger')->info('searching users'); - $searchTerm = (isset($request->get('search_user')['term']) ? $request->get('search_user')['term'] : ''); $qb = $em->getRepository('WallabagUserBundle:User')->getQueryBuilderForSearch($searchTerm); diff --git a/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php b/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php index e8e29aa9..2797efde 100644 --- a/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php +++ b/src/Wallabag/UserBundle/Mailer/AuthCodeMailer.php @@ -97,7 +97,7 @@ class AuthCodeMailer implements AuthCodeMailerInterface $message = new \Swift_Message(); $message - ->setTo($user->getEmail()) + ->setTo($user->getEmailAuthRecipient()) ->setFrom($this->senderEmail, $this->senderName) ->setSubject($subject) ->setBody($bodyText, 'text/plain') -- cgit v1.2.3 From dfd0a7bc5feb4fd7b77d7e2f3a25c5c3febc1eba Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Mon, 3 Dec 2018 06:51:06 +0100 Subject: Add backup codes --- src/Wallabag/UserBundle/Entity/User.php | 38 ++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'src/Wallabag/UserBundle') diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php index 6e305719..ab34e2bf 100644 --- a/src/Wallabag/UserBundle/Entity/User.php +++ b/src/Wallabag/UserBundle/Entity/User.php @@ -8,6 +8,7 @@ use FOS\UserBundle\Model\User as BaseUser; use JMS\Serializer\Annotation\Accessor; use JMS\Serializer\Annotation\Groups; use JMS\Serializer\Annotation\XmlRoot; +use Scheb\TwoFactorBundle\Model\BackupCodeInterface; use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface as EmailTwoFactorInterface; use Scheb\TwoFactorBundle\Model\Google\TwoFactorInterface as GoogleTwoFactorInterface; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; @@ -28,7 +29,7 @@ use Wallabag\CoreBundle\Helper\EntityTimestampsTrait; * @UniqueEntity("email") * @UniqueEntity("username") */ -class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorInterface +class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorInterface, BackupCodeInterface { use EntityTimestampsTrait; @@ -127,6 +128,11 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI */ private $googleAuthenticatorSecret; + /** + * @ORM\Column(type="json_array", nullable=true) + */ + private $backupCodes; + /** * @var bool * @@ -318,6 +324,36 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI $this->googleAuthenticatorSecret = $googleAuthenticatorSecret; } + public function setBackupCodes(array $codes = null) + { + $this->backupCodes = $codes; + } + + public function getBackupCodes() + { + return $this->backupCodes; + } + + /** + * {@inheritdoc} + */ + public function isBackupCode(string $code): bool + { + return \in_array($code, $this->backupCodes, true); + } + + /** + * {@inheritdoc} + */ + public function invalidateBackupCode(string $code): void + { + $key = array_search($code, $this->backupCodes, true); + + if (false !== $key) { + unset($this->backupCodes[$key]); + } + } + /** * @param Client $client * -- cgit v1.2.3 From 4c0e747940ac39630f1d2a6a14c628ba6729ecfd Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Fri, 7 Dec 2018 18:01:06 +0100 Subject: Remove secret from admin --- src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/Wallabag/UserBundle') diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig index 8be37e79..2de8f3a5 100644 --- a/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Manage/edit.html.twig @@ -59,12 +59,6 @@ {{ form_label(edit_form.googleTwoFactor) }} {{ form_errors(edit_form.googleTwoFactor) }}
- - {% if user.isGoogleAuthenticatorEnabled %} -
-

OTP Secret: {{ user.googleAuthenticatorSecret }}

-
- {% endif %}
{% endif %} -- cgit v1.2.3 From 4654a83b6438b88e3b7062a21d18999d9df2fb8e Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Wed, 23 Jan 2019 14:43:39 +0100 Subject: Hash backup codes in the database using `password_hash` --- src/Wallabag/UserBundle/Entity/User.php | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src/Wallabag/UserBundle') diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php index ab34e2bf..43fa6a80 100644 --- a/src/Wallabag/UserBundle/Entity/User.php +++ b/src/Wallabag/UserBundle/Entity/User.php @@ -339,7 +339,7 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI */ public function isBackupCode(string $code): bool { - return \in_array($code, $this->backupCodes, true); + return false === $this->findBackupCode($code) ? false : true; } /** @@ -347,7 +347,7 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI */ public function invalidateBackupCode(string $code): void { - $key = array_search($code, $this->backupCodes, true); + $key = $this->findBackupCode($code); if (false !== $key) { unset($this->backupCodes[$key]); @@ -385,4 +385,24 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI return $this->clients->first(); } } + + /** + * Try to find a backup code from the list of backup codes of the current user. + * + * @param string $code Given code from the user + * + * @return string|false + */ + private function findBackupCode(string $code) + { + foreach ($this->backupCodes as $key => $backupCode) { + // backup code are hashed using `password_hash` + // see ConfigController->otpAppAction + if (password_verify($code, $backupCode)) { + return $key; + } + } + + return false; + } } -- cgit v1.2.3 From 531c8d0a5c55fa93438e227a7d349235fbd31d28 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Tue, 13 Jun 2017 18:48:10 +0200 Subject: Changed RSS to Atom feed and improve paging --- src/Wallabag/UserBundle/EventListener/CreateConfigListener.php | 8 ++++---- src/Wallabag/UserBundle/Repository/UserRepository.php | 10 +++++----- src/Wallabag/UserBundle/Resources/config/services.yml | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/Wallabag/UserBundle') diff --git a/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php b/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php index 5cabfd35..81954213 100644 --- a/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php +++ b/src/Wallabag/UserBundle/EventListener/CreateConfigListener.php @@ -18,19 +18,19 @@ class CreateConfigListener implements EventSubscriberInterface private $em; private $theme; private $itemsOnPage; - private $rssLimit; + private $feedLimit; private $language; private $readingSpeed; private $actionMarkAsRead; private $listMode; private $session; - public function __construct(EntityManager $em, $theme, $itemsOnPage, $rssLimit, $language, $readingSpeed, $actionMarkAsRead, $listMode, Session $session) + public function __construct(EntityManager $em, $theme, $itemsOnPage, $feedLimit, $language, $readingSpeed, $actionMarkAsRead, $listMode, Session $session) { $this->em = $em; $this->theme = $theme; $this->itemsOnPage = $itemsOnPage; - $this->rssLimit = $rssLimit; + $this->feedLimit = $feedLimit; $this->language = $language; $this->readingSpeed = $readingSpeed; $this->actionMarkAsRead = $actionMarkAsRead; @@ -54,7 +54,7 @@ class CreateConfigListener implements EventSubscriberInterface $config = new Config($event->getUser()); $config->setTheme($this->theme); $config->setItemsPerPage($this->itemsOnPage); - $config->setRssLimit($this->rssLimit); + $config->setFeedLimit($this->feedLimit); $config->setLanguage($this->session->get('_locale', $this->language)); $config->setReadingSpeed($this->readingSpeed); $config->setActionMarkAsRead($this->actionMarkAsRead); diff --git a/src/Wallabag/UserBundle/Repository/UserRepository.php b/src/Wallabag/UserBundle/Repository/UserRepository.php index be693d3b..80391109 100644 --- a/src/Wallabag/UserBundle/Repository/UserRepository.php +++ b/src/Wallabag/UserBundle/Repository/UserRepository.php @@ -9,18 +9,18 @@ use Wallabag\UserBundle\Entity\User; class UserRepository extends EntityRepository { /** - * Find a user by its username and rss roken. + * Find a user by its username and Feed token. * * @param string $username - * @param string $rssToken + * @param string $feedToken * - * @return User|null + * @return null|User */ - public function findOneByUsernameAndRsstoken($username, $rssToken) + public function findOneByUsernameAndFeedtoken($username, $feedToken) { return $this->createQueryBuilder('u') ->leftJoin('u.config', 'c') - ->where('c.rssToken = :rss_token')->setParameter('rss_token', $rssToken) + ->where('c.feedToken = :feed_token')->setParameter('feed_token', $feedToken) ->andWhere('u.username = :username')->setParameter('username', $username) ->getQuery() ->getOneOrNullResult(); diff --git a/src/Wallabag/UserBundle/Resources/config/services.yml b/src/Wallabag/UserBundle/Resources/config/services.yml index 72cda3f8..2dcf3011 100644 --- a/src/Wallabag/UserBundle/Resources/config/services.yml +++ b/src/Wallabag/UserBundle/Resources/config/services.yml @@ -28,7 +28,7 @@ services: - "@doctrine.orm.entity_manager" - "%wallabag_core.theme%" - "%wallabag_core.items_on_page%" - - "%wallabag_core.rss_limit%" + - "%wallabag_core.feed_limit%" - "%wallabag_core.language%" - "%wallabag_core.reading_speed%" - "%wallabag_core.action_mark_as_read%" -- cgit v1.2.3 From f277bc042c8e805aab14b31b5b51e2878d80c6f4 Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Thu, 25 Apr 2019 14:12:56 +0200 Subject: Fix tests & cs & migration --- src/Wallabag/UserBundle/Repository/UserRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Wallabag/UserBundle') diff --git a/src/Wallabag/UserBundle/Repository/UserRepository.php b/src/Wallabag/UserBundle/Repository/UserRepository.php index 80391109..4abd55f1 100644 --- a/src/Wallabag/UserBundle/Repository/UserRepository.php +++ b/src/Wallabag/UserBundle/Repository/UserRepository.php @@ -14,7 +14,7 @@ class UserRepository extends EntityRepository * @param string $username * @param string $feedToken * - * @return null|User + * @return User|null */ public function findOneByUsernameAndFeedtoken($username, $feedToken) { -- cgit v1.2.3