Skip to content
Snippets Groups Projects
Commit 6663183c authored by Szász Márton's avatar Szász Márton
Browse files

pass buying and easier to exploit sqli

parent bde27fab
Branches master
No related tags found
No related merge requests found
Showing
with 450 additions and 187 deletions
{% extends 'base.html.twig' %}
{% block body %}
<form action="{{ action }}" method="get" id="buy_pass_form">
<h4 class="vspace">Új bérlet vásárlása</h4>
<div class="form-row">
{#<select name="name">#}
{#{% for passType in passTypes %}#}
{#<option value="{{ passType.name }}">{{ passType.displayName }} - {{ passType.priceHuf }} HUF</option>#}
{#{% endfor %}#}
{#</select>#}
{% for passType in passTypes %}
<div>
<label>
<input type="radio" name="name" value="{{ passType.name }}" data-price="{{ passType.priceHuf }}" required>
{{ passType.displayName }}
-
{{ passType.priceHuf }} HUF
</label>
</div>
{% endfor %}
</div>
<div class="form-row">
<input type="submit" value="Vásárlás" />
</div>
<input type="hidden" name="price" value="9500" id="buy_pass_form_pass_price" />
</form>
{% endblock %}
{% block stylesheets %}
{% endblock %}
{% extends 'base.html.twig' %}
{% block body %}
<table class="table table-striped">
<div class="profile">
<table class="table">
<h3 class="underline">Profil</h3>
<tbody>
<tr>
<td>Felhasználónév</td>
......@@ -21,6 +24,47 @@
</tr>
</tbody>
</table>
</div>
<div class="passes">
<div class="eq-flexbox underline">
<h3>Bérletek</h3>
<div class="bottom-right">
<a href="{{ path('buy_pass_page') }}">
<button class="new-pass-button">Új bérlet</button>
</a>
</div>
</div>
{% if passes|length > 0 %}
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Típus</th>
<th>Vásárlás dátuma</th>
<th>Érvényesség kezdete</th>
<th>Érvényesség vége</th>
<th>Kód</th>
</tr>
</thead>
<tbody>
{% for pass in passes %}
<tr>
<td>{{ pass.id }}</td>
<td>{{ pass.type.displayName }}</td>
<td>{{ pass.obtainDate|date('Y-m-d H:i:s') }}</td>
<td>{{ pass.validityStartDate|date('Y-m-d H:i:s') }}</td>
<td>{{ pass.validityEndDate|date('Y-m-d H:i:s') }}</td>
<td>{{ pass.code }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<em class="center">Nincs még bérlete</em>
{% endif %}
</div>
{% endblock %}
{% block stylesheets %}
......
......@@ -6,7 +6,7 @@
</div>
<ul class="nav navbar-nav">
{% if app.session.get('user') is not null %}
<li {% if _navbar_local_route == 'profile' %}class="active"{% endif %}><a href="{{ path('profile', { userId: app.session.get('user').id }) }}">Profilom</a></li>
<li {% if _navbar_local_route == 'profile' %}class="active"{% endif %}><a href="{{ path('profile', { userId: app.session.get('user').id }) }}">Profil és bérletek</a></li>
{% endif %}
</ul>
<ul class="nav navbar-nav navbar-right">
......
......@@ -37,7 +37,7 @@ framework:
twig:
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
#exception_controller: 'AppBundle:Exception:show'
exception_controller: 'AppBundle:Exception:show'
# Doctrine Configuration
doctrine:
......
......@@ -8,6 +8,10 @@
width: 100%;
}
input[type="radio"] {
width: initial;
}
input[type="text"], input[type="password"], input[type="email"] {
padding: 20px;
border: 1px solid #ccc;
......@@ -21,14 +25,6 @@
background-color: red;
}
input[type="submit"] {
padding: 20px;
background-color: cornflowerblue;
border-radius: 5px;
border: none;
font-weight: bold;
color: white;
}
// innentol a blokk vegeig stackoverflowrol loptam
// https://stackoverflow.com/questions/35942247/how-to-move-placeholder-to-top-on-focus-and-while-typing
......@@ -59,10 +55,48 @@
}
}
button, input[type="submit"] {
padding: 20px;
background-color: cornflowerblue;
border-radius: 5px;
border: none;
font-weight: bold;
color: white;
}
.vspace {
margin-top: 10px;
margin-bottom: 25px;
}
.underline {
padding: 15px 0 8px 0;
border-bottom: 1px solid #aaa;
margin-bottom: 25px;
}
.profile table tr:first-of-type td {
border: none;
}
.eq-flexbox {
display: flex;
& > * {
flex: 1;
}
}
.passes .center {
display: block;
text-align: center;
}
.passes .bottom-right {
text-align: right;
align-self: flex-end;
button {
padding: 10px 20px;
}
}
var $ = require('jquery');
require('bootstrap-sass');
(function() {
const buy_pass_form = $('#buy_pass_form');
if(buy_pass_form.length > 0) {
const price = $('#buy_pass_form_pass_price');
buy_pass_form.find('input[type="radio"]').on('click', function(event) {
const element = $(this);
price.val(element.data('price'));
});
buy_pass_form.find('input[type="submit"]').on('click', function(event) {
return confirm("Biztosan meg szeretné vásárolni a kiválasztott bérletet " + price.val() + " forintért?");
});
}
})();
\ No newline at end of file
......@@ -25,4 +25,21 @@ class Pass
/** @var \DateTimeImmutable|null */
public $validityStartDate;
/**
* Probably not secure... :)
* @return bool|string
*/
public function getCode()
{
return substr(md5($this->id), 0, 10);
}
/**
* @return \DateTimeImmutable
*/
public function getValidityEndDate()
{
return $this->validityStartDate->add(new \DateInterval('PT'.$this->type->validitySeconds.'S'));
}
}
\ No newline at end of file
......@@ -27,6 +27,7 @@ class RepositoryImpl
}
/**
* So much SQLi
* @param string $fromArg
* @param array $constraints
* @return array
......@@ -58,7 +59,10 @@ class RepositoryImpl
$sql .= ' WHERE ' . implode(' AND ', $whereargs);
}
$queryResult = $this->conn->query($sql);
//var_dump($sql);die();
$queryResult = $this->conn->prepare($sql);
$queryResult->execute();
//$queryResult = $this->conn->executeQuery($sql);
$all = $queryResult->fetchAll(\PDO::FETCH_ASSOC);
return $all;
......@@ -69,7 +73,7 @@ class RepositoryImpl
* @param int $id
* @return array
*/
public function findById(string $from, int $id): array
public function findById(string $from, $id): array
{
$result = $this->tryFindById($from, $id);
if($result !== null) {
......@@ -88,7 +92,7 @@ class RepositoryImpl
* @param int $id
* @return array|null
*/
public function tryFindById(string $from, int $id)
public function tryFindById(string $from, $id)
{
if(isset($this->cache[$from]) && isset($this->cache[$from][$id])) {
return $this->cache[$from][$id];
......
......@@ -10,6 +10,8 @@ namespace AKK\ModelBundle\Repository;
use AKK\ModelBundle\Data\Pass;
use AKK\ModelBundle\Data\PassType;
use AKK\ModelBundle\Data\User;
use AKK\ModelBundle\Repository\Detail\RepositoryImpl;
class PassRepository
......@@ -44,9 +46,8 @@ class PassRepository
*/
private function objectToArray(Pass $pass): array
{
$result = [
'id' => $pass->id
];
$result = [];
if($pass->id !== null) { $result['id'] = $pass->id; }
if($pass->type !== null) $result['pass_type_id'] = $pass->type->id;
if($pass->user !== null) $result['user_id'] = $pass->user->id;
if($pass->obtainDate !== null) $result['obtain_date'] = date('Y-m-d H:i:s', $pass->obtainDate->getTimestamp());
......@@ -62,7 +63,7 @@ class PassRepository
private function arrayToObject(array $row): Pass
{
$result = new Pass();
$result->id = $row['id'];
if(array_key_exists('id', $row)) $result->id = $row['id'];
if(array_key_exists('pass_type_id', $row)) {
$result->type = $this->passTypeRepository->lazyGetById($row['pass_type_id']);
}
......@@ -83,7 +84,7 @@ class PassRepository
* @param int $id
* @return Pass
*/
public function getById(int $id): Pass
public function getById($id): Pass
{
return $this->arrayToObject($this->repoImpl->findById(self::TABLE_NAME, $id));
}
......@@ -92,7 +93,7 @@ class PassRepository
* @param int $id
* @return Pass
*/
public function lazyGetById(int $id): Pass
public function lazyGetById($id): Pass
{
$lazyFindResult = $this->repoImpl->tryFindById(self::TABLE_NAME, $id);
if($lazyFindResult !== null) {
......@@ -107,7 +108,7 @@ class PassRepository
*/
public function persist(Pass $pass): void
{
$this->repoImpl->insert(self::TABLE_NAME, $this->objectToArray($pass));
$pass->id = $this->repoImpl->insert(self::TABLE_NAME, $this->objectToArray($pass));
}
public function initTable()
......@@ -130,6 +131,10 @@ class PassRepository
return $this->repoImpl->select(self::TABLE_NAME);
}
/**
* @param array $constraints
* @return Pass[]
*/
public function find(array $constraints): array
{
return array_map(function($row) {
......@@ -146,4 +151,28 @@ class PassRepository
if(count($result) == 0) return null;
return $result[0];
}
/**
* @param User $user
* @return Pass[]
*/
public function getByUser(User $user): array
{
return $this->find(['user_id' => $user->id]);
}
/**
* @param User $user
* @param PassType $passType
* @return Pass
*/
public function create(User $user, PassType $passType): Pass
{
$pass = new Pass();
$pass->user = $user;
$pass->type = $passType;
$pass->obtainDate = new \DateTimeImmutable('now');
$pass->validityStartDate = new \DateTimeImmutable('now');
return $pass;
}
}
\ No newline at end of file
......@@ -45,6 +45,14 @@ class PassTypeRepository
return $result;
}
private function hidrateFromArray(PassType $passType, array $row): void
{
if(array_key_exists('name', $row)) $passType->name = $row['name'];
if(array_key_exists('display_name', $row)) $passType->displayName = $row['display_name'];
if(array_key_exists('price_huf', $row)) $passType->priceHuf = $row['price_huf'];
if(array_key_exists('validity_seconds', $row)) $passType->validitySeconds = $row['validity_seconds'];
}
/**
* @param array $row
* @return PassType
......@@ -53,11 +61,7 @@ class PassTypeRepository
{
$passType = new PassType();
$passType->id = $row['id'];
if(array_key_exists('name', $row)) $passType->name = $row['name'];
if(array_key_exists('display_name', $row)) $passType->displayName = $row['display_name'];
if(array_key_exists('price_huf', $row)) $passType->priceHuf = $row['price_huf'];
if(array_key_exists('validity_seconds', $row)) $passType->validitySeconds = $row['validity_seconds'];
$this->hidrateFromArray($passType, $row);
return $passType;
}
......@@ -65,7 +69,7 @@ class PassTypeRepository
* @param int $id
* @return PassType
*/
public function getById(int $id): PassType
public function getById($id): PassType
{
return $this->arrayToObject($this->repoImpl->findById(self::TABLE_NAME, $id));
}
......@@ -74,7 +78,7 @@ class PassTypeRepository
* @param int $id
* @return PassType
*/
public function lazyGetById(int $id): PassType
public function lazyGetById($id): PassType
{
$lazyFindResult = $this->repoImpl->tryFindById(self::TABLE_NAME, $id);
if($lazyFindResult !== null) {
......@@ -118,11 +122,18 @@ class PassTypeRepository
$this->repoImpl->dropTable(self::TABLE_NAME);
}
/**
* @return PassType[]
*/
public function findAll(): array
{
return $this->repoImpl->select(self::TABLE_NAME);
return $this->find([]);
}
/**
* @param array $constraints
* @return PassType[]
*/
public function find(array $constraints): array
{
return array_map(function($row) {
......@@ -130,6 +141,11 @@ class PassTypeRepository
}, $this->repoImpl->select(self::TABLE_NAME, $constraints));
}
/**
* @param array $constraints
* @return PassType|null
* @throws \Exception
*/
public function findOne(array $constraints): PassType
{
$result = $this->find($constraints);
......@@ -139,4 +155,11 @@ class PassTypeRepository
if(count($result) == 0) return null;
return $result[0];
}
public function load(PassType $passType): void
{
if($passType->name !== null) return;
$dbres = $this->repoImpl->select(self::TABLE_NAME, ['id' => $passType->id ])[0];
$this->hidrateFromArray($passType, $dbres);
}
}
\ No newline at end of file
......@@ -66,7 +66,7 @@ class UserRepository
* @param int $id
* @return User
*/
public function getById(int $id): User
public function getById($id): User
{
return $this->findOne(['id' => $id]);
}
......@@ -75,7 +75,7 @@ class UserRepository
* @param int $id
* @return User
*/
public function lazyGetById(int $id): User
public function lazyGetById($id): User
{
$lazyFindResult = $this->repoImpl->tryFindById(self::TABLE_NAME, $id);
if($lazyFindResult !== null) {
......
......@@ -2,63 +2,21 @@
namespace AppBundle\Controller;
use AKK\ModelBundle\Data\Pass;
use AKK\ModelBundle\Data\User;
use AKK\ModelBundle\Repository\Detail\RepositoryImpl;
use AKK\ModelBundle\Repository\PassRepository;
use AKK\ModelBundle\Repository\PassTypeRepository;
use AKK\ModelBundle\Repository\UserRepository;
use Doctrine\DBAL\Connection;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Router;
class DefaultController extends Controller
{
/**
* @Route("/", name="homepage")
* @param PassTypeRepository $passTypeRepository
* @return Response
*/
public function indexAction(PassTypeRepository $passTypeRepository)
public function indexAction()
{
return $this->render('default/index.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.project_dir')).DIRECTORY_SEPARATOR,
'thing' => $passTypeRepository->findAll()
]);
}
/**
* @Route("/login", name="login", methods={"POST"})
* @param Request $request
* @param UserRepository $userRepository
* @param Router $router
* @return Response
*/
public function loginAction(Request $request, UserRepository $userRepository, Router $router)
{
if(!$request->request->has('username') || !$request->request->has('password')) {
throw $this->createAccessDeniedException('Invalid username or password.');
}
$user = $userRepository->findOne([
'username' => $request->request->get('username'),
'password' => $request->request->get('password')
]);
if($user === null) {
throw $this->createAccessDeniedException('Invalid username or password.');
}
$this->get('session')->set('user', $user);
$this->get('session')->getFlashBag()->set('success', 'Successfully logged in.');
return new RedirectResponse($router->generate('homepage'));
return $this->render('default/index.html.twig');
}
/**
......@@ -86,117 +44,16 @@ class DefaultController extends Controller
}
/**
* @Route("/reg", name="reg", methods={"POST"})
* @param Request $request
* @param UserRepository $userRepository
* @Route("/buy-pass-page", name="buy_pass_page")
* @param Router $router
* @return RedirectResponse
* @throws \Exception
*/
public function regAction(Request $request, UserRepository $userRepository, Router $router)
{
$requiredFields = ['username', 'password', 'first_name', 'last_name', 'email'];
foreach ($requiredFields as $requiredField) {
if(!$request->request->has($requiredField)) {
throw new \Exception("Field '$requiredField' is required.");
}
}
$fieldVals = $request->request->all();
$conflictingUsers = $userRepository->find([['username' => $fieldVals['username'], 'email' => $fieldVals['email']]]);
if(count($conflictingUsers) > 0) {
throw new \Exception("User name or email is already used.");
}
$user = new User();
$user->id = null;
$user->username = $fieldVals['username'];
$user->password = $fieldVals['password'];
$user->email = $fieldVals['email'];
$user->firstName = $fieldVals['first_name'];
$user->lastName = $fieldVals['last_name'];
$userRepository->persist($user);
$this->get('session')->set('user', $user);
$this->get('session')->getFlashBag()->set('success', 'Successfully registered.');
return new RedirectResponse($router->generate('homepage'));
}
public function buyPassAction(Request $request, PassTypeRepository $passTypeRepository, PassRepository $passRepository)
{
$session = $this->get('session');
if(!$session->has('user')) {
throw $this->createAccessDeniedException();
}
/** @var User $user */
$user = $session->get('user');
$price = $request->query->get('price');
$name = $request->query->get('name');
$passType = $passTypeRepository->findOne(['name' => $name]);
if($passType === null) {
throw new \Exception("Unknown pass type '$name'");
}
if($request->query->has('validity_start')) {
$validityStartDate = \DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $request->query->get('validity_start'));
} else {
$validityStartDate = new \DateTimeImmutable();
}
$pass = new Pass();
$pass->user = $user;
$pass->type = $passType;
$pass->obtainDate = new \DateTimeImmutable();
$pass->validityStartDate = $validityStartDate;
$passRepository->persist($pass);
if($pass->id !== null) {
$this->get('session')->getFlashBag()->set('success', 'Sikeres ' . lcfirst($passType->displayName) . ' vásárlás.');
} else {
throw new \Exception('Sikertelen bérletvásárlás.');
}
return $this->redirectToRoute('homepage');
}
/**
* @Route("/profile/{userId}", name="profile", methods={"GET"})
* @param int $userId
* @param UserRepository $userRepository
* @param PassTypeRepository $passTypeRepository
* @return Response
*/
public function profileAction($userId, UserRepository $userRepository)
public function buyPassPageAction(Router $router, PassTypeRepository $passTypeRepository)
{
$user = $userRepository->getById($userId);
return $this->render('default/profile.html.twig', [
'user' => $user,
return $this->render('default/buy_pass_page.html.twig', [
'action' => $router->generate('buy_pass'),
'passTypes' => $passTypeRepository->findAll()
]);
}
/**
* @param \Exception $exception
* @return Response
*/
public function exceptionAction(\Exception $exception)
{
return new Response($exception->getMessage());
}
/**
* @Route("/logout", name="logout")
* @param Session $session
* @return RedirectResponse
*/
public function logoutAction(Session $session)
{
$session->remove('user');
$session->getFlashBag()->set('success', 'Sikeres kijelentkezés.');
return $this->redirectToRoute('homepage');
}
}
<?php
/**
* Created by PhpStorm.
* User: marci
* Date: 8/16/17
* Time: 11:17 PM
*/
namespace AppBundle\Controller;
use AKK\ModelBundle\Data\Pass;
use AKK\ModelBundle\Data\User;
use AKK\ModelBundle\Repository\PassRepository;
use AKK\ModelBundle\Repository\PassTypeRepository;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Annotation\Route;
class PassController extends Controller
{
/**
* @Route("/buy-pass", name="buy_pass")
* @param Request $request
* @param PassTypeRepository $passTypeRepository
* @param PassRepository $passRepository
* @param Session $session
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Exception
*/
public function buyPassAction(Request $request, PassTypeRepository $passTypeRepository, PassRepository $passRepository, Session $session)
{
if(!$session->has('user')) {
throw $this->createAccessDeniedException();
}
/** @var User $user */
$user = $session->get('user');
$price = $request->query->get('price');
$name = $request->query->get('name');
$passType = $passTypeRepository->findOne(['name' => $name]);
if($passType === null) {
throw new \Exception("Unknown pass type '$name'");
}
if($request->query->has('validity_start')) {
$validityStartDate = \DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $request->query->get('validity_start'));
} else {
$validityStartDate = new \DateTimeImmutable();
}
$pass = new Pass();
$pass->user = $user;
$pass->type = $passType;
$pass->obtainDate = new \DateTimeImmutable();
$pass->validityStartDate = $validityStartDate;
$passRepository->persist($pass);
if($pass->id !== null) {
$session->getFlashBag()->set('success', 'Sikeres ' . lcfirst($passType->displayName) . ' vásárlás. Ár: ' . $price . ' HUF');
} else {
throw new \Exception('Sikertelen bérletvásárlás.');
}
return $this->render(':default:index.html.twig');
//return $this->redirectToRoute('homepage');
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: marci
* Date: 8/16/17
* Time: 11:13 PM
*/
namespace AppBundle\Controller;
use AKK\ModelBundle\Data\User;
use AKK\ModelBundle\Repository\PassRepository;
use AKK\ModelBundle\Repository\PassTypeRepository;
use AKK\ModelBundle\Repository\UserRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Router;
class UserController extends Controller
{
/**
* @Route("/login", name="login", methods={"POST"})
* @param Request $request
* @param UserRepository $userRepository
* @param Session $session
* @return RedirectResponse
*/
public function loginAction(Request $request, UserRepository $userRepository, Session $session)
{
if(!$request->request->has('username') || !$request->request->has('password')) {
$session->getFlashBag()->add('error', 'Hibás felhasználónév vagy jelszó.');
return $this->redirectToRoute('login');
}
$user = $userRepository->findOne([
'username' => $request->request->get('username'),
'password' => $request->request->get('password')
]);
if($user === null) {
$session->getFlashBag()->add('error', 'Hibás felhasználónév vagy jelszó.');
return $this->redirectToRoute('login');
}
$session->set('user', $user);
$session->getFlashBag()->set('success', 'Sikeres bejelentkezés.');
return $this->redirectToRoute('homepage');
}
/**
* @Route("/reg", name="reg", methods={"POST"})
* @param Request $request
* @param UserRepository $userRepository
* @param Router $router
* @param Session $session
* @return RedirectResponse
* @throws \Exception
*/
public function regAction(Request $request, UserRepository $userRepository, Router $router, Session $session)
{
$requiredFields = ['username', 'password', 'first_name', 'last_name', 'email'];
foreach ($requiredFields as $requiredField) {
if(!$request->request->has($requiredField)) {
throw new \Exception("A '$requiredField' mező kitöltése kötelező.");
}
}
$fieldVals = $request->request->all();
$byname = $userRepository->find(['username' => $fieldVals['username']]);
if(count($byname) > 0) {
throw new \Exception("Már foglalt a felhasználónév");
}
$byemail = $userRepository->find(['email' => $fieldVals['email']]);
if(count($byemail) > 0) {
throw new \Exception("Már foglalt a felhasználónév");
}
$user = new User();
$user->id = null;
$user->username = $fieldVals['username'];
$user->password = $fieldVals['password'];
$user->email = $fieldVals['email'];
$user->firstName = $fieldVals['first_name'];
$user->lastName = $fieldVals['last_name'];
$userRepository->persist($user);
$session->set('user', $user);
$session->getFlashBag()->set('success', 'Sikeres regisztráció.');
return new RedirectResponse($router->generate('homepage'));
}
/**
* @Route("/profile/{userId}", name="profile", methods={"GET"})
* @param int $userId
* @param UserRepository $userRepository
* @param PassRepository $passRepository
* @return Response
*/
public function profileAction($userId, UserRepository $userRepository, PassRepository $passRepository, PassTypeRepository $passTypeRepository)
{
$user = $userRepository->getById($userId);
$passes = $passRepository->getByUser($user);
foreach ($passes as $pass) {
$passTypeRepository->load($pass->type);
}
return $this->render('default/profile.html.twig', [
'user' => $user,
'passes' => $passes
]);
}
/**
* @Route("/logout", name="logout")
* @param Session $session
* @return RedirectResponse
*/
public function logoutAction(Session $session)
{
$session->remove('user');
$session->getFlashBag()->set('success', 'Sikeres kijelentkezés.');
return $this->redirectToRoute('homepage');
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment