Skip to content
Snippets Groups Projects
Commit ac32af21 authored by Jan-Hendrik Willms's avatar Jan-Hendrik Willms
Browse files

fixes #128, fixes #130

parent 230e8a4c
No related branches found
No related tags found
No related merge requests found
...@@ -4,12 +4,7 @@ ...@@ -4,12 +4,7 @@
<fieldset> <fieldset>
<legend><?= _('Zwei-Faktor-Authentifizierung einrichten') ?></legend> <legend><?= _('Zwei-Faktor-Authentifizierung einrichten') ?></legend>
<p> <?= formatReady(Config::get()->TFA_TEXT_INTRODUCTION) ?>
<?= _('Mittels Zwei-Faktor-Authentifizierung können Sie Ihr Konto schützen, '
. 'indem bei jedem Login ein Token von Ihnen eingegeben werden muss.') ?>
<?= _('Dieses Token erhalten Sie entweder per E-Mail oder können es über '
. 'eine geeignete Authenticator-App erzeugen lassen.') ?>
</p>
<label> <label>
<input required type="radio" name="type" value="email"> <input required type="radio" name="type" value="email">
......
<?php
final class TfaImprovedTexts extends Migration
{
public function description()
{
return 'TIC #11510: Improve texts for two factor authentication';
}
protected function up()
{
$query = "INSERT IGNORE INTO `config` (
`field`, `value`, `type`, `range`, `section`,
`mkdate`, `chdate`, `description`
) VALUES(
:id, :text, 'i18n', 'global', 'Zwei-Faktor-Authentifizierung',
UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), :description
)";
DBManager::get()->execute($query, [
':id' => 'TFA_TEXT_INTRODUCTION',
':text' => $this->getIntroductionText('de'),
':description' => 'Text, der als Einleitung beim Einrichten der Zwei-Faktor-Authentisierung angezeigt wird',
]);
DBManager::get()->execute($query, [
':id' => 'TFA_TEXT_APP',
':text' => $this->getAppText('de'),
':description' => 'Text, der als Einleitung beim Einrichten der Zwei-Faktor-Authentisierung via App angezeigt wird',
]);
$query = "INSERT IGNORE INTO `i18n` (`object_id`, `table`, `field`, `lang`, `value`)
VALUES (MD5(:id), 'config', 'value', 'en_GB', :text)";
DBManager::get()->execute($query, [
':id' => 'TFA_TEXT_INTRODUCTION',
':text' => $this->getIntroductionText('en'),
]);
DBManager::get()->execute($query, [
':id' => 'TFA_TEXT_APP',
':text' => $this->getAppText('en'),
]);
}
protected function down()
{
$query = "DELETE `config`, `config_values`
FROM `config`
LEFT JOIN `config_values` USING (`field`)
WHERE `field` IN ('TFA_TEXT_INTRODUCTION', 'TFA_TEXT_APP')";
DBManager::get()->exec($query);
$query = "DELETE FROM `i18n`
WHERE `object_id` IN (MD5('TFA_TEXT_INTRODUCTION'), MD5('TFA_TEXT_APP'))
AND `table` = 'config'
AND `field` = 'value'";
DBManager::get()->exec($query);
}
private function getIntroductionText($language)
{
if ($language === 'en') {
return 'Using two-factor authentication you can protect your account by '
. 'entering a token on each login. '
. 'You get that token either via E-Mail or by using an appropriate '
. 'authenticator app.';
} else {
return 'Mittels Zwei-Faktor-Authentifizierung können Sie Ihr Konto schützen, '
. 'indem bei jedem Login ein Token von Ihnen eingegeben werden muss. '
. 'Dieses Token erhalten Sie entweder per E-Mail oder können es über '
. 'eine geeignete Authenticator-App erzeugen lassen.';
}
}
private function getAppText($language)
{
if ($language === 'en') {
$result = "Set up a suitable OTP authenticator app for this purpose. "
. "Here you will find a list of known and compatible apps:\n";
} else {
$result = "Richten Sie dafür eine geeignete OTP-Authenticator-App ein. Hier "
. "finden Sie eine Liste bekannter und kompatibler Apps:\n";
}
return $result . $this->getAuthenticatorList();
}
private function getAuthenticatorList()
{
return implode("\n", [
'- [Authy]https://authy.com/',
'- [FreeOTP]https://freeotp.github.io/',
'- Google Authenticator: [Android]https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2 oder [iOS]https://apps.apple.com/app/google-authenticator/id388497605',
'- [LastPass Authenticator]https://lastpass.com/auth/',
'- [Microsoft Authenticator]https://www.microsoft.com/authenticator',
]);
}
}
<?php
final class TfaTrustDuration extends Migration
{
public function description()
{
return 'TIC #11508: Configurable trust duration for devices';
}
protected function up()
{
// Create course config
$query = "INSERT IGNORE INTO `config` (
`field`, `value`, `type`, `range`, `section`,
`mkdate`, `chdate`,
`description`
) VALUES(
'TFA_TRUST_DURATION', '30', 'integer', 'global', 'Zwei-Faktor-Authentifizierung',
UNIX_TIMESTAMP(), UNIX_TIMESTAMP(),
'Dauer, denen Geräte vertraut werden soll in Tagen (0 für dauerhaftes Vertrauen)'
)";
DBManager::get()->exec($query);
}
protected function down()
{
$query = "DELETE `config`, `config_values`
FROM `config`
LEFT JOIN `config_values` USING (`field`)
WHERE `field` = 'TFA_TRUST_DURATION'";
DBManager::get()->exec($query);
}
}
...@@ -221,9 +221,10 @@ final class TwoFactorAuth ...@@ -221,9 +221,10 @@ final class TwoFactorAuth
echo $GLOBALS['template_factory']->render( echo $GLOBALS['template_factory']->render(
'tfa-validate.php', 'tfa-validate.php',
$_SESSION[self::SESSION_DATA] + [ $_SESSION[self::SESSION_DATA] + [
'secret' => $this->secret, 'secret' => $this->secret,
'text' => $text, 'text' => $text,
'blocked' => $this->isBlocked(), 'blocked' => $this->isBlocked(),
'duration' => Config::get()->TFA_TRUST_DURATION,
], ],
'layouts/base.php' 'layouts/base.php'
); );
...@@ -250,11 +251,14 @@ final class TwoFactorAuth ...@@ -250,11 +251,14 @@ final class TwoFactorAuth
*/ */
private function registerSecretInCookie() private function registerSecretInCookie()
{ {
$lifetime_in_days = Config::get()->TFA_TRUST_DURATION;
$lifetime = $lifetime_in_days > 0 ? strtotime("+{$lifetime_in_days} days") : 2147483647;
$timeslice = mt_rand(0, PHP_INT_MAX); $timeslice = mt_rand(0, PHP_INT_MAX);
setcookie( setcookie(
self::COOKIE_KEY, self::COOKIE_KEY,
implode(':', [$this->secret->getToken($timeslice), $timeslice]), implode(':', [$this->secret->getToken($timeslice), $timeslice]),
strtotime('+30 days'), $lifetime,
$GLOBALS['CANONICAL_RELATIVE_PATH_STUDIP'] $GLOBALS['CANONICAL_RELATIVE_PATH_STUDIP']
); );
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
<? else: ?> <? else: ?>
<p><?= htmlReady($text ?: _('Bitte geben Sie ein gültiges Token ein')) ?></p> <p><?= htmlReady($text ?: _('Bitte geben Sie ein gültiges Token ein')) ?></p>
<? if ($secret->type === 'app' && !$secret->confirmed): ?> <? if ($secret->type === 'app' && !$secret->confirmed): ?>
<?= formatReady(Config::get()->TFA_TEXT_APP) ?>
<p> <p>
<?= _('Scannen Sie diesen Code mit Ihrer App ein und geben Sie ' <?= _('Scannen Sie diesen Code mit Ihrer App ein und geben Sie '
. 'anschliessend ein gültiges Token ein.') ?> . 'anschliessend ein gültiges Token ein.') ?>
...@@ -53,7 +54,18 @@ ...@@ -53,7 +54,18 @@
<? if ($global): ?> <? if ($global): ?>
<label> <label>
<input type="checkbox" name="tfa-trusted" value="1"> <input type="checkbox" name="tfa-trusted" value="1">
<?= _('Diesem Gerät für 30 Tage vertrauen.') ?> <? if ($duration > 0): ?>
<?= sprintf(
ngettext(
'Diesem Gerät für %u Tag vertrauen.',
'Diesem Gerät für %u Tage vertrauen.',
$duration
),
$duration
) ?>
<? else: ?>
<?= _('Diesem Gerät dauerhaft vertrauen') ?>
<? endif; ?>
</label> </label>
<? endif; ?> <? endif; ?>
</fieldset> </fieldset>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment