Basic login functionality added.
This commit is contained in:
parent
d953e8a319
commit
ef29705a37
|
@ -1,7 +1,11 @@
|
|||
security:
|
||||
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
|
||||
providers:
|
||||
in_memory: { memory: ~ }
|
||||
app_db_provider:
|
||||
entity:
|
||||
class: App\Entity\User
|
||||
property: username
|
||||
manager_name: default
|
||||
encoders:
|
||||
App\Entity\User:
|
||||
algorithm: 'argon2i'
|
||||
|
@ -12,19 +16,29 @@ security:
|
|||
dev:
|
||||
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
||||
security: false
|
||||
main:
|
||||
api:
|
||||
pattern: ^/api/
|
||||
anonymous: true
|
||||
main:
|
||||
pattern: ^/
|
||||
anonymous: ~
|
||||
provider: app_db_provider
|
||||
form_login:
|
||||
login_path: user_login
|
||||
check_path: user_login
|
||||
logout:
|
||||
path: user_logout
|
||||
target: /
|
||||
remember_me:
|
||||
secret: '%kernel.secret%'
|
||||
lifetime: 604800
|
||||
path: /
|
||||
always_remember_me: true
|
||||
|
||||
# activate different ways to authenticate
|
||||
|
||||
# http_basic: true
|
||||
# https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
|
||||
|
||||
# form_login: true
|
||||
# https://symfony.com/doc/current/security/form_login_setup.html
|
||||
|
||||
# Easy way to control access for large sections of your site
|
||||
# Note: Only the *first* access control that matches will be used
|
||||
access_control:
|
||||
# - { path: ^/admin, roles: ROLE_ADMIN }
|
||||
# - { path: ^/profile, roles: ROLE_USER }
|
||||
- { path: ^/$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||
- { path: /login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
|
||||
- { path: ^/, roles: ROLE_USER }
|
||||
|
|
|
@ -4,7 +4,7 @@ index:
|
|||
controller: App\Controller\MainController::index
|
||||
|
||||
torrents_search:
|
||||
path: /torrents/search
|
||||
path: /torrents
|
||||
controller: App\Controller\TorrentController::searchTorrent
|
||||
requirements:
|
||||
method: GET
|
||||
|
@ -23,6 +23,13 @@ user_register:
|
|||
method: GET
|
||||
inviteCode: \w{32}
|
||||
|
||||
user_login:
|
||||
path: /login
|
||||
controller: App\Controller\SecurityController::login
|
||||
|
||||
user_logout:
|
||||
path: /logout
|
||||
|
||||
# API
|
||||
api_v1_torrents:
|
||||
path: /api/v1/torrents
|
||||
|
|
|
@ -2,16 +2,29 @@
|
|||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Magnetico\Repository\TorrentRepository;
|
||||
use App\Form\LoginType;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class MainController extends Controller
|
||||
{
|
||||
public function index(TorrentRepository $repo): Response
|
||||
public function index(): Response
|
||||
{
|
||||
return $this->render('index.html.twig', [
|
||||
'torrentsCount' => $repo->getTorrentsTotalCount(),
|
||||
'loginForm' => $this->createLoginForm('')->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
private function createLoginForm(string $username): FormInterface
|
||||
{
|
||||
$form = $this->createForm(LoginType::class, null, [
|
||||
'action' => $this->generateUrl('user_login'),
|
||||
]);
|
||||
$form->get('_username')->setData($username);
|
||||
$form->add('submit', SubmitType::class);
|
||||
|
||||
return $form;
|
||||
}
|
||||
}
|
40
src/Controller/SecurityController.php
Normal file
40
src/Controller/SecurityController.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Form\LoginType;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||
use Symfony\Component\Form\{FormError, FormInterface};
|
||||
use Symfony\Component\HttpFoundation\{Request, Response};
|
||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
|
||||
class SecurityController extends Controller
|
||||
{
|
||||
public function login(Request $request, AuthenticationUtils $authenticationUtils, TranslatorInterface $translator): Response
|
||||
{
|
||||
$lastError = $authenticationUtils->getLastAuthenticationError() ? $authenticationUtils->getLastAuthenticationError()->getMessage() : '';
|
||||
$lastUsername = $authenticationUtils->getLastUsername();
|
||||
|
||||
$form = $this->createLoginForm($lastUsername);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($lastError) {
|
||||
$form->addError(new FormError($lastError));
|
||||
}
|
||||
|
||||
return $this->render('Security/login.html.twig', ['form' => $form->createView()]);
|
||||
}
|
||||
|
||||
private function createLoginForm(string $username): FormInterface
|
||||
{
|
||||
$form = $this->createForm(LoginType::class, null, [
|
||||
'action' => $this->generateUrl('user_login'),
|
||||
]);
|
||||
$form->get('_username')->setData($username);
|
||||
$form->add('submit', SubmitType::class);
|
||||
|
||||
return $form;
|
||||
}
|
||||
}
|
26
src/Form/LoginType.php
Normal file
26
src/Form/LoginType.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\{PasswordType, TextType};
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class LoginType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('_username', TextType::class, ['mapped' => false])
|
||||
->add('_password', PasswordType::class, ['mapped' => false])
|
||||
;
|
||||
}
|
||||
|
||||
public function getBlockPrefix()
|
||||
{
|
||||
// Empty prefix for default UsernamePasswordFrormAuthenticationListener
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
}
|
7
templates/Security/login.html.twig
Normal file
7
templates/Security/login.html.twig
Normal file
|
@ -0,0 +1,7 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div id="form-login">
|
||||
{{ form(form) }}
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -26,16 +26,25 @@
|
|||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
|
||||
{% if is_granted('IS_AUTHENTICATED_REMEMBERED') %}
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<!--<li class="nav-item">
|
||||
<a class="nav-link" href="#">Item</a>
|
||||
</li>-->
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle" role="button" data-toggle="dropdown">
|
||||
{{ app.user.username }}
|
||||
</a>
|
||||
<div class="dropdown-menu">
|
||||
<a href="{{ path('user_logout') }}" class="dropdown-item">Logout</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if is_granted('ROLE_USER') %}
|
||||
<form class="form-inline my-2 my-lg-0" action="{{ path('torrents_search') }}" method="get">
|
||||
<input name="query" class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search"
|
||||
value="{% if searchQuery is defined %}{{ searchQuery }}{% endif %}">
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
{% block content %}
|
||||
<div class="well">
|
||||
<p>Torrents indexed: {{ torrentsCount }}</p>
|
||||
{% if not is_granted('ROLE_USER') %}
|
||||
<a href="{{ path('user_login') }}" class="btn btn-lg btn-primary">Login</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
Loading…
Reference in a new issue