Prefer U2F as 2FA method if it is available.

This commit is contained in:
Jan Böhmer 2019-12-29 17:36:41 +01:00
parent 39aaab07c5
commit b5e80ec1b7
3 changed files with 35 additions and 14 deletions

View file

@ -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) 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. * Get either a Gravatar URL or complete image tag for a specified email address.
* *

View file

@ -35,13 +35,14 @@ class UserSettingsController extends AbstractController
public function showBackupCodes() public function showBackupCodes()
{ {
$user = $this->getUser(); $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. //When user change its settings, he should be logged in fully.
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_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())) { if (empty($user->getBackupCodes())) {
$this->addFlash('error', 'You do not have any backup codes enabled, therefore you can not view them!'); $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!'); 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) public function removeU2FToken(Request $request, EntityManagerInterface $entityManager, BackupCodeManager $backupCodeManager)
{ {
$user = $this->getUser(); $user = $this->getUser();
//When user change its settings, he should be logged in fully.
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
if (!$user instanceof User) { if (!$user instanceof User) {
throw new \RuntimeException('This controller only works only for Part-DB User objects!'); 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 ($this->isCsrfTokenValid('delete'.$user->getId(), $request->request->get('_token'))) {
if($request->request->has('key_id')) { if($request->request->has('key_id')) {
@ -101,11 +105,14 @@ class UserSettingsController extends AbstractController
public function resetTrustedDevices(Request $request, EntityManagerInterface $entityManager) public function resetTrustedDevices(Request $request, EntityManagerInterface $entityManager)
{ {
$user = $this->getUser(); $user = $this->getUser();
//When user change its settings, he should be logged in fully.
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
if (!$user instanceof User) { if (!$user instanceof User) {
return new \RuntimeException('This controller only works only for Part-DB User objects!'); 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'))) { if ($this->isCsrfTokenValid('devices_reset'.$user->getId(), $request->request->get('_token'))) {
$user->invalidateTrustedDeviceTokens(); $user->invalidateTrustedDeviceTokens();
@ -130,13 +137,13 @@ class UserSettingsController extends AbstractController
$page_need_reload = false; $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. //When user change its settings, he should be logged in fully.
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_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 * User settings form
***************************/ ***************************/

View file

@ -65,6 +65,7 @@ use Doctrine\ORM\Mapping as ORM;
use R\U2FTwoFactorBundle\Model\U2F\TwoFactorKeyInterface; use R\U2FTwoFactorBundle\Model\U2F\TwoFactorKeyInterface;
use Scheb\TwoFactorBundle\Model\BackupCodeInterface; use Scheb\TwoFactorBundle\Model\BackupCodeInterface;
use Scheb\TwoFactorBundle\Model\Google\TwoFactorInterface; use Scheb\TwoFactorBundle\Model\Google\TwoFactorInterface;
use Scheb\TwoFactorBundle\Model\PreferredProviderInterface;
use Scheb\TwoFactorBundle\Model\TrustedDeviceInterface; use Scheb\TwoFactorBundle\Model\TrustedDeviceInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface; 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") * @UniqueEntity("name", message="validator.user.username_already_used")
*/ */
class User extends AttachmentContainingDBElement implements UserInterface, HasPermissionsInterface, class User extends AttachmentContainingDBElement implements UserInterface, HasPermissionsInterface,
TwoFactorInterface, BackupCodeInterface, TrustedDeviceInterface, U2FTwoFactorInterface TwoFactorInterface, BackupCodeInterface, TrustedDeviceInterface, U2FTwoFactorInterface, PreferredProviderInterface
{ {
use MasterAttachmentTrait; use MasterAttachmentTrait;
@ -845,4 +846,18 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
{ {
$this->u2fKeys->removeElement($key); $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;
}
} }