Moved user settings and 2FA related controller into its own class UserSettingsController.

This commit is contained in:
Jan Böhmer 2019-12-29 17:17:12 +01:00
parent 16bc257b17
commit 39aaab07c5
3 changed files with 270 additions and 237 deletions

View file

@ -153,178 +153,6 @@ class UserController extends AdminPages\BaseAdminController
]);
}
/**
* @Route("/2fa_backup_codes", name="show_backup_codes")
*/
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 (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!');
}
return $this->render('Users/backup_codes.html.twig', [
'user' => $user
]);
}
/**
* @Route("/settings", name="user_settings")
*/
public function userSettings(Request $request, EntityManagerInterface $em, UserPasswordEncoderInterface $passwordEncoder, GoogleAuthenticator $googleAuthenticator, BackupCodeManager $backupCodeManager)
{
/**
* @var User
*/
$user = $this->getUser();
$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');
/***************************
* User settings form
***************************/
$form = $this->createForm(UserSettingsType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
//Check if user theme setting has changed
if ($user->getTheme() !== $em->getUnitOfWork()->getOriginalEntityData($user)['theme']) {
$page_need_reload = true;
}
$em->flush();
$this->addFlash('success', 'user.settings.saved_flash');
}
/*****************************
* Password change form
****************************/
$demo_mode = $this->getParameter('demo_mode');
$pw_form = $this->createFormBuilder()
//Username field for autocomplete
->add('username', TextType::class, [
'data' => $user->getName(),
'attr' => ['autocomplete' => 'username'],
'disabled' => true,
'row_attr' => ['class' => 'd-none']
])
->add('old_password', PasswordType::class, [
'label' => 'user.settings.pw_old.label',
'disabled' => $demo_mode,
'attr' => ['autocomplete' => 'current-password'],
'constraints' => [new UserPassword()], ]) //This constraint checks, if the current user pw was inputted.
->add('new_password', RepeatedType::class, [
'disabled' => $demo_mode,
'type' => PasswordType::class,
'first_options' => ['label' => 'user.settings.pw_new.label'],
'second_options' => ['label' => 'user.settings.pw_confirm.label'],
'invalid_message' => 'password_must_match',
'options' => [
'attr' => ['autocomplete' => 'new-password']
],
'constraints' => [new Length([
'min' => 6,
'max' => 128,
])],
])
->add('submit', SubmitType::class, ['label' => 'save'])
->getForm();
$pw_form->handleRequest($request);
//Check if password if everything was correct, then save it to User and DB
if ($pw_form->isSubmitted() && $pw_form->isValid()) {
$password = $passwordEncoder->encodePassword($user, $pw_form['new_password']->getData());
$user->setPassword($password);
//After the change reset the password change needed setting
$user->setNeedPwChange(false);
$em->persist($user);
$em->flush();
$this->addFlash('success', 'user.settings.pw_changed_flash');
}
//Handle 2FA things
$google_form = $this->createForm(TFAGoogleSettingsType::class, $user);
$google_enabled = $user->isGoogleAuthenticatorEnabled();
if (!$form->isSubmitted() && !$google_enabled) {
$user->setGoogleAuthenticatorSecret($googleAuthenticator->generateSecret());
$google_form->get('googleAuthenticatorSecret')->setData($user->getGoogleAuthenticatorSecret());
}
$google_form->handleRequest($request);
if($google_form->isSubmitted() && $google_form->isValid()) {
if (!$google_enabled) {
//Save 2FA settings (save secrets)
$user->setGoogleAuthenticatorSecret($google_form->get('googleAuthenticatorSecret')->getData());
$backupCodeManager->enableBackupCodes($user);
$em->flush();
$this->addFlash('success', 'user.settings.2fa.google.activated');
return $this->redirectToRoute('user_settings');
} elseif ($google_enabled) {
//Remove secret to disable google authenticator
$user->setGoogleAuthenticatorSecret(null);
$backupCodeManager->disableBackupCodesIfUnused($user);
$em->flush();
$this->addFlash('success', 'user.settings.2fa.google.disabled');
return $this->redirectToRoute('user_settings');
}
}
$backup_form = $this->get('form.factory')->createNamedBuilder('backup_codes')->add('reset_codes', SubmitType::class,[
'label' => 'tfa_backup.regenerate_codes',
'attr' => ['class' => 'btn-danger'],
'disabled' => empty($user->getBackupCodes())
])->getForm();
$backup_form->handleRequest($request);
if ($backup_form->isSubmitted() && $backup_form->isValid()) {
$backupCodeManager->regenerateBackupCodes($user);
$em->flush();
$this->addFlash('success', 'user.settings.2fa.backup_codes.regenerated');
}
/******************************
* Output both forms
*****************************/
return $this->render('Users/user_settings.html.twig', [
'user' => $user,
'settings_form' => $form->createView(),
'pw_form' => $pw_form->createView(),
'page_need_reload' => $page_need_reload,
'google_form' => $google_form->createView(),
'backup_form' => $backup_form->createView(),
'tfa_google' => [
'enabled' => $google_enabled,
'qrContent' => $googleAuthenticator->getQRContent($user),
'secret' => $user->getGoogleAuthenticatorSecret(),
'username' => $user->getGoogleAuthenticatorUsername()
]
]);
}
/**
* Get either a Gravatar URL or complete image tag for a specified email address.