diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 0f07ee14..78ff39d4 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -82,7 +82,7 @@ class UserController extends AdminPages\BaseAdminController } /** - * @Route("/{id}", name="user_delete", methods={"DELETE"}) + * @Route("/{id}", name="user_delete", methods={"DELETE"}, requirements={"id"="\d+"}) */ public function delete(Request $request, User $entity, StructuralElementRecursionHelper $recursionHelper) { @@ -153,7 +153,6 @@ class UserController extends AdminPages\BaseAdminController ]); } - /** * Get either a Gravatar URL or complete image tag for a specified email address. * diff --git a/src/Controller/UserSettingsController.php b/src/Controller/UserSettingsController.php index b337fe7d..afc1bfaf 100644 --- a/src/Controller/UserSettingsController.php +++ b/src/Controller/UserSettingsController.php @@ -35,13 +35,14 @@ class UserSettingsController extends AbstractController public function showBackupCodes() { $user = $this->getUser(); - if (!$user instanceof User) { - return new \RuntimeException('This controller only works only for Part-DB User objects!'); - } //When user change its settings, he should be logged in fully. $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY'); + if (!$user instanceof User) { + return new \RuntimeException('This controller only works only for Part-DB User objects!'); + } + if (empty($user->getBackupCodes())) { $this->addFlash('error', 'You do not have any backup codes enabled, therefore you can not view them!'); throw new Exception('You do not have any backup codes enabled, therefore you can not view them!'); @@ -60,11 +61,14 @@ class UserSettingsController extends AbstractController public function removeU2FToken(Request $request, EntityManagerInterface $entityManager, BackupCodeManager $backupCodeManager) { $user = $this->getUser(); + + //When user change its settings, he should be logged in fully. + $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY'); + if (!$user instanceof User) { throw new \RuntimeException('This controller only works only for Part-DB User objects!'); } - //When user change its settings, he should be logged in fully. - $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY'); + if ($this->isCsrfTokenValid('delete'.$user->getId(), $request->request->get('_token'))) { if($request->request->has('key_id')) { @@ -101,11 +105,14 @@ class UserSettingsController extends AbstractController public function resetTrustedDevices(Request $request, EntityManagerInterface $entityManager) { $user = $this->getUser(); + + //When user change its settings, he should be logged in fully. + $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY'); + if (!$user instanceof User) { return new \RuntimeException('This controller only works only for Part-DB User objects!'); } - //When user change its settings, he should be logged in fully. - $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY'); + if ($this->isCsrfTokenValid('devices_reset'.$user->getId(), $request->request->get('_token'))) { $user->invalidateTrustedDeviceTokens(); @@ -130,13 +137,13 @@ class UserSettingsController extends AbstractController $page_need_reload = false; - if (!$user instanceof User) { - return new \RuntimeException('This controller only works only for Part-DB User objects!'); - } - //When user change its settings, he should be logged in fully. $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY'); + if (!$user instanceof User) { + throw new \RuntimeException('This controller only works only for Part-DB User objects!'); + } + /*************************** * User settings form ***************************/ diff --git a/src/Entity/UserSystem/User.php b/src/Entity/UserSystem/User.php index 21c20e45..9f60e15f 100644 --- a/src/Entity/UserSystem/User.php +++ b/src/Entity/UserSystem/User.php @@ -65,6 +65,7 @@ use Doctrine\ORM\Mapping as ORM; use R\U2FTwoFactorBundle\Model\U2F\TwoFactorKeyInterface; use Scheb\TwoFactorBundle\Model\BackupCodeInterface; use Scheb\TwoFactorBundle\Model\Google\TwoFactorInterface; +use Scheb\TwoFactorBundle\Model\PreferredProviderInterface; use Scheb\TwoFactorBundle\Model\TrustedDeviceInterface; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Security\Core\User\UserInterface; @@ -80,7 +81,7 @@ use R\U2FTwoFactorBundle\Model\U2F\TwoFactorInterface as U2FTwoFactorInterface; * @UniqueEntity("name", message="validator.user.username_already_used") */ class User extends AttachmentContainingDBElement implements UserInterface, HasPermissionsInterface, - TwoFactorInterface, BackupCodeInterface, TrustedDeviceInterface, U2FTwoFactorInterface + TwoFactorInterface, BackupCodeInterface, TrustedDeviceInterface, U2FTwoFactorInterface, PreferredProviderInterface { use MasterAttachmentTrait; @@ -845,4 +846,18 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe { $this->u2fKeys->removeElement($key); } + + /** + * @inheritDoc + */ + public function getPreferredTwoFactorProvider(): ?string + { + //If U2F is available then prefer it + if($this->isU2FAuthEnabled()) { + return 'u2f_two_factor'; + } + + //Otherwise use other methods + return null; + } }