2024.12.01 23:47:39

This commit is contained in:
Christian Moser 2024-12-01 23:47:39 +01:00
parent 68d4bec756
commit ff0ab7be47
8 changed files with 109 additions and 32 deletions

View File

@ -33,6 +33,12 @@ security:
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
remember_me:
secret: '%kernel.secret%'
# three weeks lifetime (in seconds)
lifetime: 1814400
token_provider:
doctrine: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used

View File

@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20241201211313 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE rememberme_token (series VARCHAR(88) NOT NULL, value VARCHAR(88) NOT NULL, lastUsed DATETIME NOT NULL --(DC2Type:datetime_immutable)
, class VARCHAR(100) NOT NULL, username VARCHAR(200) NOT NULL, PRIMARY KEY(series))');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP TABLE rememberme_token');
}
}

View File

@ -7,7 +7,9 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends AbstractController
use App\Controller\WebrootController;
class SecurityController extends WebrootController
{
#[Route(path: '/login', name: 'app_login')]
public function login(AuthenticationUtils $authenticationUtils): Response
@ -18,10 +20,16 @@ class SecurityController extends AbstractController
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
]);
return $this->render('security/login.html.twig', array_merge(
$this->getControllerVariables(), [
'login_title' => $this->trans("login.title",domain:"security"),
'login_button' => $this->trans("login.button",domain:"security"),
'login_username' => $this->trans("login.username",domain:"security"),
'login_password' => $this->trans("login.password",domain:"security"),
'login_remember_me' => $this->trans("login.remember_me",domain:"security"),
'last_username' => $lastUsername,
'error' => $error,
]));
}
#[Route(path: '/logout', name: 'app_logout')]

View File

@ -5,16 +5,23 @@ namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use \Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use App\Utility\NullTranslator;
abstract class WebrootController extends AbstractController
{
private ?string $project_dir = null;
private ?TranslatorInterface $tranlsator = null;
protected ?NullTranslator $nulltranslator = null;
public function __construct(KernelInterface $kernel)
public function __construct(KernelInterface $kernel,TranslatorInterface $translator)
{
$this->project_dir = $kernel->getProjectDir();
$this->translator = $translator;
$this->nulltranslator = new NullTranslator();
}
public function getHeaderTitleFiglet(): ?string
@ -39,4 +46,9 @@ abstract class WebrootController extends AbstractController
"header_title" => $this->getHeaderTitleFiglet(),
];
}
public function trans(string $message,array $args=[],string $domain="messages",?string $locale=null): string
{
return $this->translator->trans($message,$args,domain:$domain,locale:$locale);
}
}

View File

@ -21,7 +21,6 @@ __ _____| |__ _ __ ___ ___ | |_
\ \ /\ / / _ \ '_ \| '__/ _ \ / _ \| __|
\ V V / __/ |_) | | | (_) | (_) | |_
\_/\_/ \___|_.__/|_| \___/ \___/ \__|
123
</pre></div>{% endif %}
{% endblock %}
</header>

View File

@ -2,7 +2,7 @@
{% block title %}Log in!{% endblock %}
{% block body %}
{% block main %}
<form method="post">
{% if error %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
@ -13,29 +13,37 @@
You are logged in as {{ app.user.userIdentifier }}, <a href="{{ path('app_logout') }}">Logout</a>
</div>
{% endif %}
<fieldset style="min-width: 400px;max-width: 650px;" class="center">
<legend><h3 class="h3 mb-3 font-weight-normal">{{ login_title }}</h3></legend>
<table class="full-width">
<tr>
<th class="shrink-to-fit standard-background left">
<label for="username">{{ login_username }}</label>
</th>
<td class="full-width left">
<input type="text" value="{{ last_username }}" name="_username" id="username" class="form-control full-width" autocomplete="username" required autofocus>
</td>
</tr>
<tr>
<th class="shrink-to-fit standard-background left">
<label for="password">{{ login_password }}</label>
</th>
<td class="full-width left">
<input type="password" name="_password" id="password" class="form-control full-width" autocomplete="current-password" required>
</td>
<tr>
<tr>
<td colspan="2" class="left">
<input type="checkbox" name="_remember_me" id="_remember_me">
<label for="_remember_me">{{ login_remember_me }}</label>
</td>
</tr>
</table>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<label for="username">Username</label>
<input type="text" value="{{ last_username }}" name="_username" id="username" class="form-control" autocomplete="username" required autofocus>
<label for="password">Password</label>
<input type="password" name="_password" id="password" class="form-control" autocomplete="current-password" required>
<input type="hidden" name="_csrf_token"
value="{{ csrf_token('authenticate') }}"
>
{#
Uncomment this section and add a remember_me option below your firewall to activate remember me functionality.
See https://symfony.com/doc/current/security/remember_me.html
<div class="checkbox mb-3">
<input type="checkbox" name="_remember_me" id="_remember_me">
<label for="_remember_me">Remember me</label>
</div>
#}
<button class="btn btn-lg btn-primary" type="submit">
Sign in
</button>
<button class="btn btn-lg btn-primary" type="submit" class="right">{{ login_button }}</button>
</fieldset>
</form>
{% endblock %}

View File

@ -17,3 +17,9 @@
'Invalid or expired login link.': 'Ungültiger oder abgelaufener Anmelde-Link.'
'Too many failed login attempts, please try again in %minutes% minute.': 'Zu viele fehlgeschlagene Anmeldeversuche, bitte versuchen Sie es in einer Minute noch einmal.'
'Too many failed login attempts, please try again in %minutes% minutes.': 'Zu viele fehlgeschlagene Anmeldeversuche, bitte versuchen Sie es in %minutes% Minuten noch einmal.'
login:
title: "Bitte melde dich an"
button: "Anmelden"
username: "Nutzername"
password: "Passwort"
remember_me: "An mich erinnern"

View File

@ -17,3 +17,9 @@
'Invalid or expired login link.': 'Invalid or expired login link.'
'Too many failed login attempts, please try again in %minutes% minute.': 'Too many failed login attempts, please try again in %minutes% minute.'
'Too many failed login attempts, please try again in %minutes% minutes.': 'Too many failed login attempts, please try again in %minutes% minutes.'
login:
title: "Please sign in"
button: "Log me in"
username: "Username"
password: "Password"
remember_me: "Remember me"