Change the way to enable 2FA

And add a step to validate a generated code from the OTP app
This commit is contained in:
Jeremy Benoist 2019-01-18 22:46:44 +01:00
parent 4c0e747940
commit a0c5eb003f
No known key found for this signature in database
GPG key ID: BCA73962457ACC3C
20 changed files with 620 additions and 293 deletions

View file

@ -81,28 +81,7 @@ class ConfigController extends Controller
]);
$userForm->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 === $userForm->isSubmitted()) {
$userForm->get('googleTwoFactor')->setData(true);
}
if ($userForm->isSubmitted() && $userForm->isValid()) {
// handle creation / reset of the OTP secret if checkbox changed from the previous state
if ($this->getParameter('twofactor_auth')) {
if (true === $userForm->get('googleTwoFactor')->getData() && false === $user->isGoogleAuthenticatorEnabled()) {
$secret = $this->get('scheb_two_factor.security.google_authenticator')->generateSecret();
$user->setGoogleAuthenticatorSecret($secret);
$user->setEmailTwoFactor(false);
$user->setBackupCodes((new BackupCodes())->toArray());
$this->addFlash('OtpQrCode', $this->get('scheb_two_factor.security.google_authenticator')->getQRContent($user));
} elseif (false === $userForm->get('googleTwoFactor')->getData() && true === $user->isGoogleAuthenticatorEnabled()) {
$user->setGoogleAuthenticatorSecret(null);
$user->setBackupCodes(null);
}
}
$userManager->updateUser($user, true);
$this->addFlash(
@ -175,11 +154,118 @@ class ConfigController extends Controller
],
'twofactor_auth' => $this->getParameter('twofactor_auth'),
'wallabag_url' => $this->getParameter('domain_name'),
'enabled_users' => $this->get('wallabag_user.user_repository')
->getSumEnabledUsers(),
'enabled_users' => $this->get('wallabag_user.user_repository')->getSumEnabledUsers(),
]);
}
/**
* Enable 2FA using email.
*
* @param Request $request
*
* @Route("/config/otp/email", name="config_otp_email")
*/
public function otpEmailAction(Request $request)
{
if (!$this->getParameter('twofactor_auth')) {
return $this->createNotFoundException('two_factor not enabled');
}
$user = $this->getUser();
$user->setGoogleAuthenticatorSecret(null);
$user->setBackupCodes(null);
$user->setEmailTwoFactor(true);
$this->container->get('fos_user.user_manager')->updateUser($user, true);
$this->addFlash(
'notice',
'flashes.config.notice.otp_enabled'
);
return $this->redirect($this->generateUrl('config') . '#set3');
}
/**
* Enable 2FA using OTP app, user will need to confirm the generated code from the app.
*
* @Route("/config/otp/app", name="config_otp_app")
*/
public function otpAppAction()
{
if (!$this->getParameter('twofactor_auth')) {
return $this->createNotFoundException('two_factor not enabled');
}
$user = $this->getUser();
if (!$user->isGoogleTwoFactor()) {
$secret = $this->get('scheb_two_factor.security.google_authenticator')->generateSecret();
$user->setGoogleAuthenticatorSecret($secret);
$user->setEmailTwoFactor(false);
$user->setBackupCodes((new BackupCodes())->toArray());
$this->container->get('fos_user.user_manager')->updateUser($user, true);
}
return $this->render('WallabagCoreBundle:Config:otp_app.html.twig', [
'qr_code' => $this->get('scheb_two_factor.security.google_authenticator')->getQRContent($user),
]);
}
/**
* Cancelling 2FA using OTP app.
*
* @Route("/config/otp/app/cancel", name="config_otp_app_cancel")
*/
public function otpAppCancelAction()
{
if (!$this->getParameter('twofactor_auth')) {
return $this->createNotFoundException('two_factor not enabled');
}
$user = $this->getUser();
$user->setGoogleAuthenticatorSecret(null);
$user->setBackupCodes(null);
$this->container->get('fos_user.user_manager')->updateUser($user, true);
return $this->redirect($this->generateUrl('config') . '#set3');
}
/**
* Validate OTP code.
*
* @param Request $request
*
* @Route("/config/otp/app/check", name="config_otp_app_check")
*/
public function otpAppCheckAction(Request $request)
{
$isValid = $this->get('scheb_two_factor.security.google_authenticator')->checkCode(
$this->getUser(),
$request->get('_auth_code')
);
if (true === $isValid) {
$this->addFlash(
'notice',
'flashes.config.notice.otp_enabled'
);
return $this->redirect($this->generateUrl('config') . '#set3');
}
$this->addFlash(
'two_factor',
'scheb_two_factor.code_invalid'
);
return $this->redirect($this->generateUrl('config_otp_app'));
}
/**
* @param Request $request
*

View file

@ -102,12 +102,16 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Navn'
email_label: 'Emailadresse'
two_factor:
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Or use that code:'
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# table_method: Method
# table_state: State
# table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete:
# title: Delete my account (a.k.a danger zone)
# description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out.
@ -165,6 +169,15 @@ config:
# and: 'One rule AND another'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry:
# default_title: 'Title of the entry'

View file

@ -102,12 +102,16 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Name'
email_label: 'E-Mail-Adresse'
two_factor:
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Or use that code:'
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# table_method: Method
# table_state: State
# table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete:
title: 'Lösche mein Konto (a.k.a Gefahrenzone)'
description: 'Wenn du dein Konto löschst, werden ALL deine Artikel, ALL deine Tags, ALL deine Anmerkungen und dein Konto dauerhaft gelöscht (kann NICHT RÜCKGÄNGIG gemacht werden). Du wirst anschließend ausgeloggt.'

View file

@ -102,12 +102,16 @@ config:
two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Name'
email_label: 'Email'
two_factor:
emailTwoFactor_label: 'Using email (receive a code by email)'
googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
two_factor_code_description_2: 'You can scan that QR Code with your app:'
two_factor_code_description_3: 'Or use that code:'
two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
table_method: Method
table_state: State
table_action: Action
state_enabled: Enabled
state_disabled: Disabled
action_email: Use email
action_app: Use OTP App
delete:
title: Delete my account (a.k.a danger zone)
description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out.
@ -165,6 +169,15 @@ config:
and: 'One rule AND another'
matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
page_title: Two-factor authentication
app:
two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
two_factor_code_description_2: 'You can scan that QR Code with your app:'
two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
two_factor_code_description_4: 'Test an OTP code from your configured app:'
cancel: Cancel
enable: Enable
entry:
default_title: 'Title of the entry'
@ -584,6 +597,7 @@ flashes:
tags_reset: Tags reset
entries_reset: Entries reset
archived_reset: Archived entries deleted
otp_enabled: Two-factor authentication enabled
entry:
notice:
entry_already_saved: 'Entry already saved on %date%'

View file

@ -102,12 +102,16 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Nombre'
email_label: 'Dirección de e-mail'
two_factor:
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Or use that code:'
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# table_method: Method
# table_state: State
# table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete:
title: Eliminar mi cuenta (Zona peligrosa)
description: Si eliminas tu cuenta, TODOS tus artículos, TODAS tus etiquetas, TODAS tus anotaciones y tu cuenta serán eliminadas de forma PERMANENTE (no se puede deshacer). Después serás desconectado.
@ -165,6 +169,15 @@ config:
and: 'Una regla Y la otra'
matches: 'Prueba si un <i>sujeto</i> corresponde a una <i>búsqueda</i> (insensible a mayusculas).<br />Ejemplo : <code>title matches "fútbol"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry:
default_title: 'Título del artículo'

View file

@ -102,12 +102,16 @@ config:
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'نام'
email_label: 'نشانی ایمیل'
two_factor:
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Or use that code:'
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# table_method: Method
# table_state: State
# table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete:
# title: Delete my account (a.k.a danger zone)
# description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out.
@ -165,6 +169,15 @@ config:
# and: 'One rule AND another'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry:
# default_title: 'Title of the entry'

View file

@ -102,12 +102,16 @@ config:
two_factor_description: "Activer lauthentification double-facteur veut dire que vous allez recevoir un code par courriel OU que vous devriez utiliser une application de mot de passe à usage unique (comme Google Authenticator, Authy or FreeOTP) pour obtenir un code temporaire à chaque nouvelle connexion non approuvée. Vous ne pouvez pas choisir les deux options."
name_label: "Nom"
email_label: "Adresse courriel"
two_factor:
emailTwoFactor_label: 'En utlisant lemail (recevez un code par email)'
googleTwoFactor_label: 'En utilisant une application de mot de passe à usage unique (ouvrez lapp, comme Google Authenticator, Authy or FreeOTP, pour obtenir un mot de passe à usage unique)'
two_factor_code_description_1: Vous venez dactiver lauthentification double-facteur, ouvrez votre application OTP pour configurer la génération du mot de passe à usage unique. Ces informations disparaîtront après un rechargement de la page.
two_factor_code_description_2: 'Vous pouvez scanner le QR code avec votre application :'
two_factor_code_description_3: 'Ou utiliser le code suivant :'
two_factor_code_description_4: 'Noubliez pas de sauvegarder ces codes de secours dans un endroit sûr, vous pourrez les utiliser si vous ne pouvez plus accéder à votre application OTP :'
table_method: Méthode
table_state: État
table_action: Action
state_enabled: Activé
state_disabled: Désactivé
action_email: Utiliser l'email
action_app: Utiliser une app OTP
delete:
title: "Supprimer mon compte (attention danger !)"
description: "Si vous confirmez la suppression de votre compte, TOUS les articles, TOUS les tags, TOUTES les annotations et votre compte seront DÉFINITIVEMENT supprimé (cest IRRÉVERSIBLE). Vous serez ensuite déconnecté."
@ -165,6 +169,15 @@ config:
and: "Une règle ET lautre"
matches: "Teste si un <i>sujet</i> correspond à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title matches \"football\"</code>"
notmatches: "Teste si un <i>sujet</i> ne correspond pas à une <i>recherche</i> (non sensible à la casse).<br />Exemple : <code>title notmatches \"football\"</code>"
otp:
page_title: Authentification double-facteur
app:
two_factor_code_description_1: Vous venez dactiver lauthentification double-facteur, ouvrez votre application OTP pour configurer la génération du mot de passe à usage unique. Ces informations disparaîtront après un rechargement de la page.
two_factor_code_description_2: 'Vous pouvez scanner le QR code avec votre application :'
two_factor_code_description_3: 'Noubliez pas de sauvegarder ces codes de secours dans un endroit sûr, vous pourrez les utiliser si vous ne pouvez plus accéder à votre application OTP :'
two_factor_code_description_4: 'Testez un code généré par votre application OTP :'
cancel: Annuler
enable: Activer
entry:
default_title: "Titre de larticle"
@ -585,6 +598,7 @@ flashes:
tags_reset: "Tags supprimés"
entries_reset: "Articles supprimés"
archived_reset: "Articles archivés supprimés"
otp_enabled: "Authentification à double-facteur activée"
entry:
notice:
entry_already_saved: "Article déjà sauvegardé le %date%"

View file

@ -104,10 +104,13 @@ config:
email_label: 'E-mail'
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Or use that code:'
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# table_method: Method
# table_state: State
# table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete:
title: Cancella il mio account (zona pericolosa)
description: Rimuovendo il tuo account, TUTTI i tuoi articoli, TUTTE le tue etichette, TUTTE le tue annotazioni ed il tuo account verranno rimossi PERMANENTEMENTE (impossibile da ANNULLARE). Verrai poi disconnesso.
@ -165,6 +168,15 @@ config:
and: "Una regola E un'altra"
matches: 'Verifica che un <i>oggetto</i> risulti in una <i>ricerca</i> (case-insensitive).<br />Esempio: <code>titolo contiene "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry:
default_title: "Titolo del contenuto"

View file

@ -104,10 +104,13 @@ config:
email_label: 'Adreça de corrièl'
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Or use that code:'
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# table_method: Method
# table_state: State
# table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete:
title: Suprimir mon compte (Mèfi zòna perilhosa)
description: Se confirmatz la supression de vòstre compte, TOTES vòstres articles, TOTAS vòstras etiquetas, TOTAS vòstras anotacions e vòstre compte seràn suprimits per totjorn. E aquò es IRREVERSIBLE. Puèi seretz desconnectat.
@ -165,6 +168,15 @@ config:
and: "Una règla E l'autra"
matches: 'Teste se un <i>subjècte</i> correspond a una <i>recèrca</i> (non sensibla a la cassa).<br />Exemple:<code>title matches \"football\"</code>'
notmatches: 'Teste se <i>subjècte</i> correspond pas a una <i>recèrca</i> (sensibla a la cassa).<br />Example:<code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry:
default_title: "Títol de l'article"

View file

@ -99,15 +99,18 @@ config:
all: 'Wszystkie'
rss_limit: 'Link do RSS'
form_user:
two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
# two_factor_description: "Enabling two factor authentication means you'll receive an email with a code OR need to use an OTP app (like Google Authenticator, Authy or FreeOTP) to get a one time code on every new untrusted connection. You can't choose both option."
name_label: 'Nazwa'
email_label: 'Adres email'
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Or use that code:'
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# table_method: Method
# table_state: State
# table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete:
title: Usuń moje konto (niebezpieczna strefa !)
description: Jeżeli usuniesz swoje konto, wszystkie twoje artykuły, tagi, adnotacje, oraz konto zostaną trwale usunięte (operacja jest NIEODWRACALNA). Następnie zostaniesz wylogowany.
@ -165,6 +168,15 @@ config:
and: 'Jedna reguła I inna'
matches: 'Sprawdź czy <i>temat</i> pasuje <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł zawiera "piłka nożna"</code>'
notmatches: 'Sprawdź czy <i>temat</i> nie zawiera <i>szukaj</i> (duże lub małe litery).<br />Przykład: <code>tytuł nie zawiera "piłka nożna"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry:
default_title: 'Tytuł wpisu'

View file

@ -104,10 +104,13 @@ config:
email_label: 'E-mail'
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Or use that code:'
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# table_method: Method
# table_state: State
# table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete:
# title: Delete my account (a.k.a danger zone)
# description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out.
@ -165,6 +168,15 @@ config:
and: 'Uma regra E outra'
matches: 'Testa que um <i>assunto</i> corresponde a uma <i>pesquisa</i> (maiúscula ou minúscula).<br />Exemplo: <code>título corresponde a "futebol"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry:
default_title: 'Título da entrada'

View file

@ -104,10 +104,13 @@ config:
email_label: 'E-mail'
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Or use that code:'
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# table_method: Method
# table_state: State
# table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete:
# title: Delete my account (a.k.a danger zone)
# description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out.
@ -165,6 +168,15 @@ config:
# and: 'One rule AND another'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry:
# default_title: 'Title of the entry'

View file

@ -101,10 +101,13 @@ config:
email_label: 'Email'
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Or use that code:'
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# table_method: Method
# table_state: State
# table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete:
title: "Удалить мой аккаунт (или опасная зона)"
description: "Если Вы удалите ваш аккаунт, ВСЕ ваши записи, теги и другие данные, будут БЕЗВОЗВРАТНО удалены (операция не может быть отменена после). Затем Вы выйдете из системы."
@ -160,6 +163,15 @@ config:
or: 'Одно правило ИЛИ другое'
and: 'Одно правило И другое'
matches: 'Тесты, в которых <i> тема </i> соответствует <i> поиску </i> (без учета регистра). Пример: <code> title matches "футбол" </code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry:
default_title: 'Название записи'

View file

@ -104,10 +104,13 @@ config:
email_label: 'อีเมล'
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Or use that code:'
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# table_method: Method
# table_state: State
# table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete:
title: ลบบัญชีของฉัน (โซนที่เป็นภัย!)
description: ถ้าคุณลบบัญชีของคุณIf , รายการทั้งหมดของคุณ, แท็กทั้งหมดของคุณ, หมายเหตุทั้งหมดของคุณและบัญชีของคุณจะถูกลบอย่างถาวร (มันไม่สามารถยกเลิกได้) คุณจะต้องลงชื่อออก
@ -165,6 +168,15 @@ config:
and: 'หนึ่งข้อบังคับและอื่นๆ'
matches: 'ทดสอบว่า <i>เรื่อง</i> นี้ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อที่ตรงกับ "football"</code>'
notmatches: 'ทดสอบว่า <i>เรื่อง</i> นี้ไม่ตรงกับ <i>การต้นหา</i> (กรณีไม่ทราบ).<br />ตัวอย่าง: <code>หัวข้อทีไม่ตรงกับ "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry:
default_title: 'หัวข้อรายการ'

View file

@ -104,10 +104,13 @@ config:
email_label: 'E-posta'
# emailTwoFactor_label: 'Using email (receive a code by email)'
# googleTwoFactor_label: 'Using an OTP app (open the app, like Google Authenticator, Authy or FreeOTP, to get a one time code)'
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Or use that code:'
# two_factor_code_description_4: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# table_method: Method
# table_state: State
# table_action: Action
# state_enabled: Enabled
# state_disabled: Disabled
# action_email: Use email
# action_app: Use OTP App
delete:
# title: Delete my account (a.k.a danger zone)
# description: If you remove your account, ALL your articles, ALL your tags, ALL your annotations and your account will be PERMANENTLY removed (it can't be UNDONE). You'll then be logged out.
@ -165,6 +168,15 @@ config:
and: 'Bir kural ve diğeri'
# matches: 'Tests that a <i>subject</i> matches a <i>search</i> (case-insensitive).<br />Example: <code>title matches "football"</code>'
# notmatches: 'Tests that a <i>subject</i> doesn''t match match a <i>search</i> (case-insensitive).<br />Example: <code>title notmatches "football"</code>'
otp:
# page_title: Two-factor authentication
# app:
# two_factor_code_description_1: You just enabled the OTP two factor authentication, open your OTP app and use that code to get a one time password. It'll disapear after a page reload.
# two_factor_code_description_2: 'You can scan that QR Code with your app:'
# two_factor_code_description_3: 'Also, save these backup codes in a safe place, you can use them in case you lose access to your OTP app:'
# two_factor_code_description_4: 'Test an OTP code from your configured app:'
# cancel: Cancel
# enable: Enable
entry:
default_title: 'Makalenin başlığı'

View file

@ -168,48 +168,41 @@
</div>
</fieldset>
{{ form_widget(form.user.save) }}
{% if twofactor_auth %}
<h5>{{ 'config.otp.page_title'|trans }}</h5>
<div class="row">
{{ 'config.form_user.two_factor_description'|trans }}
</div>
<fieldset class="w500p inline">
<div class="row">
{{ form_label(form.user.emailTwoFactor) }}
{{ form_errors(form.user.emailTwoFactor) }}
{{ form_widget(form.user.emailTwoFactor) }}
</div>
<br/>
<div class="row">
{{ form_label(form.user.googleTwoFactor) }}
{{ form_widget(form.user.googleTwoFactor) }}
{{ form_errors(form.user.googleTwoFactor) }}
</div>
{% for OtpQrCode in app.session.flashbag.get('OtpQrCode') %}
<div class="row">
{{ 'config.form_user.two_factor_code_description_1'|trans }}
<br/>
{{ 'config.form_user.two_factor_code_description_2'|trans }}
<br/><br/>
<img id="2faQrcode" class="hide-on-med-and-down" />
<script>
document.getElementById('2faQrcode').src = jrQrcode.getQrBase64('{{ OtpQrCode }}');
</script>
<br/><br/>
{{ 'config.form_user.two_factor_code_description_3'|trans }}
<br/><br/>
<strong>{{ app.user.getGoogleAuthenticatorSecret }}</strong>
<br/><br/>
{{ 'config.form_user.two_factor_code_description_4'|trans }}
<br/><br/>
<strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong>
</div>
{% endfor %}
</fieldset>
<table>
<thead>
<tr>
<th>{{ 'config.form_user.two_factor.table_method'|trans }}</th>
<th>{{ 'config.form_user.two_factor.table_state'|trans }}</th>
<th>{{ 'config.form_user.two_factor.table_action'|trans }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ 'config.form_user.two_factor.emailTwoFactor_label'|trans }}</td>
<td>{% if app.user.isEmailTwoFactor %}<b>{{ 'config.form_user.two_factor.state_enabled'|trans }}</b>{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}</td>
<td><a href="{{ path('config_otp_email') }}" class="waves-effect waves-light btn{% if app.user.isEmailTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_email'|trans }}</a></td>
</tr>
<tr>
<td>{{ 'config.form_user.two_factor.googleTwoFactor_label'|trans }}</td>
<td>{% if app.user.isGoogleTwoFactor %}<b>{{ 'config.form_user.two_factor.state_enabled'|trans }}</b>{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}</td>
<td><a href="{{ path('config_otp_app') }}" class="waves-effect waves-light btn{% if app.user.isGoogleTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_app'|trans }}</a></td>
</tr>
</tbody>
</table>
{% endif %}
{{ form_widget(form.user._token) }}
{{ form_widget(form.user.save) }}
</form>
{% if enabled_users > 1 %}

View file

@ -0,0 +1,55 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{{ 'config.page_title'|trans }} > {{ 'config.otp.page_title'|trans }}{% endblock %}
{% block content %}
<h5>{{ 'config.otp.page_title'|trans }}</h5>
<ol>
<li>
<p>{{ 'config.otp.app.two_factor_code_description_1'|trans }}</p>
<p>{{ 'config.otp.app.two_factor_code_description_2'|trans }}</p>
<p>
<img id="2faQrcode" class="hide-on-med-and-down" />
<script>
document.getElementById('2faQrcode').src = jrQrcode.getQrBase64('{{ qr_code }}');
</script>
</p>
</li>
<li>
<p>{{ 'config.otp.app.two_factor_code_description_3'|trans }}</p>
<p><strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong></p>
</li>
<li>
<p>{{ 'config.otp.app.two_factor_code_description_4'|trans }}</p>
{% for flashMessage in app.session.flashbag.get("two_factor") %}
<div class="card-panel red darken-1 black-text">
{{ flashMessage|trans }}
</div>
{% endfor %}
<form class="form" action="{{ path("config_otp_app_check") }}" method="post">
<div class="card-content">
<div class="row">
<div class="input-field col s12">
<label for="_auth_code">{{ "scheb_two_factor.auth_code"|trans }}</label>
<input id="_auth_code" type="text" autocomplete="off" name="_auth_code" />
</div>
</div>
</div>
<div class="card-action">
<a href="{{ path('config_otp_app_cancel') }}" class="waves-effect waves-light grey btn">
{{ 'config.otp.app.cancel'|trans }}
</a>
<button class="btn waves-effect waves-light" type="submit" name="send">
{{ 'config.otp.app.enable'|trans }}
<i class="material-icons right">send</i>
</button>
</div>
</form>
</li>
</ol>
{% endblock %}

View file

@ -196,45 +196,40 @@
</div>
</div>
{% if twofactor_auth %}
<div class="row">
{{ 'config.form_user.two_factor_description'|trans }}
<div class="input-field col s11">
{{ form_widget(form.user.emailTwoFactor) }}
{{ form_label(form.user.emailTwoFactor) }}
{{ form_errors(form.user.emailTwoFactor) }}
</div>
<div class="input-field col s11">
{{ form_widget(form.user.googleTwoFactor) }}
{{ form_label(form.user.googleTwoFactor) }}
{{ form_errors(form.user.googleTwoFactor) }}
</div>
</div>
{% for OtpQrCode in app.session.flashbag.get('OtpQrCode') %}
<div class="card-panel yellow darken-1 black-text">
{{ 'config.form_user.two_factor_code_description_1'|trans }}
<br/>
{{ 'config.form_user.two_factor_code_description_2'|trans }}
<br/><br/>
<img id="2faQrcode" class="hide-on-med-and-down" />
<script>
document.getElementById('2faQrcode').src = jrQrcode.getQrBase64('{{ OtpQrCode }}');
</script>
<br/><br/>
{{ 'config.form_user.two_factor_code_description_3'|trans }}
<br/><br/>
<strong>{{ app.user.getGoogleAuthenticatorSecret }}</strong>
<br/><br/>
{{ 'config.form_user.two_factor_code_description_4'|trans }}
<br/><br/>
<strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong>
</div>
{% endfor %}
{% endif %}
{{ form_widget(form.user.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
{% if twofactor_auth %}
<br/>
<br/>
<div class="row">
<h5>{{ 'config.otp.page_title'|trans }}</h5>
<p>{{ 'config.form_user.two_factor_description'|trans }}</p>
<table>
<thead>
<tr>
<th>{{ 'config.form_user.two_factor.table_method'|trans }}</th>
<th>{{ 'config.form_user.two_factor.table_state'|trans }}</th>
<th>{{ 'config.form_user.two_factor.table_action'|trans }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ 'config.form_user.two_factor.emailTwoFactor_label'|trans }}</td>
<td>{% if app.user.isEmailTwoFactor %}<b>{{ 'config.form_user.two_factor.state_enabled'|trans }}</b>{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}</td>
<td><a href="{{ path('config_otp_email') }}" class="waves-effect waves-light btn{% if app.user.isEmailTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_email'|trans }}</a></td>
</tr>
<tr>
<td>{{ 'config.form_user.two_factor.googleTwoFactor_label'|trans }}</td>
<td>{% if app.user.isGoogleTwoFactor %}<b>{{ 'config.form_user.two_factor.state_enabled'|trans }}</b>{% else %}{{ 'config.form_user.two_factor.state_disabled'|trans }}{% endif %}</td>
<td><a href="{{ path('config_otp_app') }}" class="waves-effect waves-light btn{% if app.user.isGoogleTwoFactor %} disabled{% endif %}">{{ 'config.form_user.two_factor.action_app'|trans }}</a></td>
</tr>
</tbody>
</table>
</div>
{% endif %}
{{ form_widget(form.user._token) }}
</form>
</div>

View file

@ -0,0 +1,63 @@
{% extends "WallabagCoreBundle::layout.html.twig" %}
{% block title %}{{ 'config.page_title'|trans }} > {{ 'config.otp.page_title'|trans }}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card-panel settings">
<div class="row">
<h5>{{ 'config.otp.page_title'|trans }}</h5>
<ol>
<li>
<p>{{ 'config.otp.app.two_factor_code_description_1'|trans }}</p>
<p>{{ 'config.otp.app.two_factor_code_description_2'|trans }}</p>
<p>
<img id="2faQrcode" class="hide-on-med-and-down" />
<script>
document.getElementById('2faQrcode').src = jrQrcode.getQrBase64('{{ qr_code }}');
</script>
</p>
</li>
<li>
<p>{{ 'config.otp.app.two_factor_code_description_3'|trans }}</p>
<p><strong>{{ app.user.getBackupCodes|join("\n")|nl2br }}</strong></p>
</li>
<li>
<p>{{ 'config.otp.app.two_factor_code_description_4'|trans }}</p>
{% for flashMessage in app.session.flashbag.get("two_factor") %}
<div class="card-panel red darken-1 black-text">
{{ flashMessage|trans }}
</div>
{% endfor %}
<form class="form" action="{{ path("config_otp_app_check") }}" method="post">
<div class="card-content">
<div class="row">
<div class="input-field col s12">
<label for="_auth_code">{{ "scheb_two_factor.auth_code"|trans }}</label>
<input id="_auth_code" type="text" autocomplete="off" name="_auth_code" />
</div>
</div>
</div>
<div class="card-action">
<a href="{{ path('config_otp_app_cancel') }}" class="waves-effect waves-light grey btn">
{{ 'config.otp.app.cancel'|trans }}
</a>
<button class="btn waves-effect waves-light" type="submit" name="send">
{{ 'config.otp.app.enable'|trans }}
<i class="material-icons right">send</i>
</button>
</div>
</form>
</li>
</ol>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -297,119 +297,6 @@ class ConfigControllerTest extends WallabagCoreTestCase
$this->assertContains('flashes.config.notice.user_updated', $alert[0]);
}
public function testUserEnable2faEmail()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('button[id=update_user_save]')->form();
$data = [
'update_user[emailTwoFactor]' => '1',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
$this->assertContains('flashes.config.notice.user_updated', $alert[0]);
// restore user
$em = $this->getEntityManager();
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertTrue($user->isEmailTwoFactor());
$user->setEmailTwoFactor(false);
$em->persist($user);
$em->flush();
}
public function testUserEnable2faGoogle()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('button[id=update_user_save]')->form();
$data = [
'update_user[googleTwoFactor]' => '1',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
$this->assertContains('flashes.config.notice.user_updated', $alert[0]);
// restore user
$em = $this->getEntityManager();
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertTrue($user->isGoogleAuthenticatorEnabled());
$user->setGoogleAuthenticatorSecret(null);
$em->persist($user);
$em->flush();
}
public function testUserEnable2faBoth()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config');
$this->assertSame(200, $client->getResponse()->getStatusCode());
$form = $crawler->filter('button[id=update_user_save]')->form();
$data = [
'update_user[googleTwoFactor]' => '1',
'update_user[emailTwoFactor]' => '1',
];
$client->submit($form, $data);
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
$this->assertContains('flashes.config.notice.user_updated', $alert[0]);
// restore user
$em = $this->getEntityManager();
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertTrue($user->isGoogleAuthenticatorEnabled());
$this->assertFalse($user->isEmailTwoFactor());
$user->setGoogleAuthenticatorSecret(null);
$em->persist($user);
$em->flush();
}
public function testRssUpdateResetToken()
{
$this->logInAs('admin');
@ -1113,4 +1000,85 @@ class ConfigControllerTest extends WallabagCoreTestCase
$this->assertNotSame('yuyuyuyu', $client->getRequest()->getLocale());
$this->assertNotSame('yuyuyuyu', $client->getContainer()->get('session')->get('_locale'));
}
public function testUserEnable2faEmail()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config/otp/email');
$this->assertSame(302, $client->getResponse()->getStatusCode());
$crawler = $client->followRedirect();
$this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
$this->assertContains('flashes.config.notice.otp_enabled', $alert[0]);
// restore user
$em = $this->getEntityManager();
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertTrue($user->isEmailTwoFactor());
$user->setEmailTwoFactor(false);
$em->persist($user);
$em->flush();
}
public function testUserEnable2faGoogle()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config/otp/app');
$this->assertSame(200, $client->getResponse()->getStatusCode());
// restore user
$em = $this->getEntityManager();
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertTrue($user->isGoogleTwoFactor());
$this->assertGreaterThan(0, $user->getBackupCodes());
$user->setGoogleAuthenticatorSecret(false);
$user->setBackupCodes(null);
$em->persist($user);
$em->flush();
}
public function testUserEnable2faGoogleCancel()
{
$this->logInAs('admin');
$client = $this->getClient();
$crawler = $client->request('GET', '/config/otp/app');
$this->assertSame(200, $client->getResponse()->getStatusCode());
// restore user
$em = $this->getEntityManager();
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertTrue($user->isGoogleTwoFactor());
$this->assertGreaterThan(0, $user->getBackupCodes());
$crawler = $client->request('GET', '/config/otp/app/cancel');
$this->assertSame(302, $client->getResponse()->getStatusCode());
$user = $em
->getRepository('WallabagUserBundle:User')
->findOneByUsername('admin');
$this->assertFalse($user->isGoogleTwoFactor());
$this->assertEmpty($user->getBackupCodes());
}
}