Permet à l'utilisateur de se connecter
This commit is contained in:
@@ -8,9 +8,10 @@ require __DIR__ . '/../src/Silex/Config/Config.php';
|
||||
$loader = new SplClassLoader('Silex', __DIR__ . '/../src');
|
||||
$loader->register();
|
||||
|
||||
$controller = new \Silex\Controller\UserController();
|
||||
$security = new \Silex\Controller\SecurityController();
|
||||
$user = new \Silex\Controller\UserController();
|
||||
$router = new Router($_SERVER['REQUEST_URI']);
|
||||
$router->get('/^$/', [$controller, 'index']);
|
||||
$router->get('/^news\/(?<id>[\w-]+)$/', [$controller, 'viewPost']);
|
||||
//$router->get('/^inscription$/', [$controller, 'connexion']);
|
||||
$router->run(new \Silex\DI\DI())->render(__DIR__ . '/../' . VIEW_PATH);
|
||||
$router->get('/^$/', [$user, 'index']);
|
||||
$router->get('/^news\/(?<id>[\w-]+)$/', [$user, 'viewPost']);
|
||||
$router->match('/^login$/', [$security, 'login']);
|
||||
$router->run(new \Silex\DI\DI($router))->render(__DIR__ . '/../' . VIEW_PATH);
|
||||
|
27
src/Silex/Controller/SecurityController.php
Normal file
27
src/Silex/Controller/SecurityController.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Silex\Controller;
|
||||
|
||||
use Silex\DI\DI;
|
||||
use Silex\Http\HttpResponse;
|
||||
|
||||
class SecurityController
|
||||
{
|
||||
public function login(DI $di): HttpResponse
|
||||
{
|
||||
$fail = false;
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$success = $di->getSecurity()->initLogin($_POST['login'], $_POST['password']);
|
||||
if ($success) {
|
||||
http_response_code(303);
|
||||
header('Location: ' . $di->getRouter()->url(''));
|
||||
exit();
|
||||
}
|
||||
var_dump($success);
|
||||
$fail = !$success;
|
||||
}
|
||||
return HttpResponse::found('login', ['fail' => $fail]);
|
||||
}
|
||||
}
|
@@ -6,11 +6,27 @@ namespace Silex\DI;
|
||||
|
||||
use Silex\Gateway\NewsGateway;
|
||||
use PDO;
|
||||
use Silex\Gateway\UserGateway;
|
||||
use Silex\Router\Router;
|
||||
use Silex\Security\Security;
|
||||
|
||||
class DI
|
||||
{
|
||||
private Router $router;
|
||||
private ?PDO $pdo = null;
|
||||
private ?NewsGateway $newsGateway = null;
|
||||
private ?UserGateway $userGateway = null;
|
||||
private ?Security $security = null;
|
||||
|
||||
public function __construct(Router $router)
|
||||
{
|
||||
$this->router = $router;
|
||||
}
|
||||
|
||||
public function getRouter(): Router
|
||||
{
|
||||
return $this->router;
|
||||
}
|
||||
|
||||
public function getNewsGateway(): NewsGateway
|
||||
{
|
||||
@@ -20,6 +36,23 @@ class DI
|
||||
return $this->newsGateway;
|
||||
}
|
||||
|
||||
public function getUserGateway(): UserGateway
|
||||
{
|
||||
if ($this->userGateway === null) {
|
||||
$this->userGateway = new UserGateway($this->getPDO());
|
||||
}
|
||||
return $this->userGateway;
|
||||
}
|
||||
|
||||
public function getSecurity(): Security
|
||||
{
|
||||
if ($this->security === null) {
|
||||
session_start();
|
||||
$this->security = new Security($this->getUserGateway(), $_SESSION);
|
||||
}
|
||||
return $this->security;
|
||||
}
|
||||
|
||||
private function getPDO(): PDO
|
||||
{
|
||||
if ($this->pdo === null) {
|
||||
|
36
src/Silex/Gateway/UserGateway.php
Normal file
36
src/Silex/Gateway/UserGateway.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Silex\Gateway;
|
||||
|
||||
use PDO;
|
||||
use Silex\Model\User;
|
||||
|
||||
class UserGateway
|
||||
{
|
||||
private PDO $pdo;
|
||||
|
||||
public function __construct(PDO $pdo)
|
||||
{
|
||||
$this->pdo = $pdo;
|
||||
}
|
||||
|
||||
public function getById(int $id): ?User
|
||||
{
|
||||
$req = $this->pdo->prepare('SELECT * FROM registered_user WHERE id_user = :id');
|
||||
$req->execute(['id' => $id]);
|
||||
$req->setFetchMode(PDO::FETCH_CLASS, User::class);
|
||||
$user = $req->fetch();
|
||||
return $user === false ? null : $user;
|
||||
}
|
||||
|
||||
public function getByLogin(string $login): ?User
|
||||
{
|
||||
$req = $this->pdo->prepare('SELECT * FROM registered_user WHERE login = :login;');
|
||||
$req->execute(['login' => $login]);
|
||||
$req->setFetchMode(PDO::FETCH_CLASS, User::class);
|
||||
$user = $req->fetch();
|
||||
return $user === false ? null : $user;
|
||||
}
|
||||
}
|
@@ -19,6 +19,11 @@ class HttpResponse
|
||||
$this->viewParams = $viewParams;
|
||||
}
|
||||
|
||||
public static function found(string $viewPath, array $viewParams = []): HttpResponse
|
||||
{
|
||||
return new HttpResponse(200, $viewPath, $viewParams);
|
||||
}
|
||||
|
||||
public function render(string $viewBasePath)
|
||||
{
|
||||
$params = $this->viewParams;
|
||||
|
41
src/Silex/Model/User.php
Normal file
41
src/Silex/Model/User.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Silex\Model;
|
||||
|
||||
class User
|
||||
{
|
||||
private int $id_user;
|
||||
private string $login;
|
||||
private string $password;
|
||||
private int $role;
|
||||
|
||||
public static function fromRawPassword(string $login, string $password): User
|
||||
{
|
||||
$user = new User();
|
||||
$user->login = $login;
|
||||
$user->password = password_hash($password, PASSWORD_DEFAULT);
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id_user;
|
||||
}
|
||||
|
||||
public function getLogin(): string
|
||||
{
|
||||
return $this->login;
|
||||
}
|
||||
|
||||
public function getPasswordHash(): string
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
public function getRole(): int
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
}
|
@@ -14,4 +14,9 @@ final class PathHelper
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
public static function startsWith(string $haystack, string $needle): bool
|
||||
{
|
||||
return strpos($haystack, $needle) === 0;
|
||||
}
|
||||
}
|
||||
|
@@ -9,9 +9,10 @@ use Silex\DI\DI;
|
||||
|
||||
class Router
|
||||
{
|
||||
|
||||
private string $url;
|
||||
|
||||
private string $basePath = '';
|
||||
|
||||
/**
|
||||
* @var Route[]
|
||||
*/
|
||||
@@ -26,32 +27,47 @@ class Router
|
||||
|
||||
public function setBasePath(string $basePath)
|
||||
{
|
||||
$pos = strpos($this->url, $basePath);
|
||||
if ($pos === false) {
|
||||
$this->url = null;
|
||||
} else {
|
||||
$this->url = trim(substr($this->url, $pos + strlen($basePath)), '/');
|
||||
if (PathHelper::startsWith($this->url, $basePath)) {
|
||||
$this->url = trim(substr($this->url, strlen($basePath)), '/');
|
||||
}
|
||||
$this->basePath = $basePath;
|
||||
}
|
||||
|
||||
public function get(string $path, callable $callable): self
|
||||
{
|
||||
return $this->addRoute('GET', $path, $callable);
|
||||
return $this->addRoute(['GET'], $path, $callable);
|
||||
}
|
||||
|
||||
private function addRoute(string $method, string $path, $callable): self
|
||||
public function post(string $path, callable $callable): self
|
||||
{
|
||||
return $this->addRoute(['GET'], $path, $callable);
|
||||
}
|
||||
|
||||
public function match(string $path, callable $callable): self
|
||||
{
|
||||
return $this->addRoute(['GET', 'POST'], $path, $callable);
|
||||
}
|
||||
|
||||
private function addRoute(array $methods, string $path, $callable): self
|
||||
{
|
||||
$route = new Route($path, $callable);
|
||||
$this->routes[$method][] = $route;
|
||||
foreach ($methods as $method) {
|
||||
$this->routes[$method][] = $route;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function url(string $url): string
|
||||
{
|
||||
return $this->basePath . '/' . $url;
|
||||
}
|
||||
|
||||
public function run(DI $di): HttpResponse
|
||||
{
|
||||
if (!isset($this->routes[$_SERVER['REQUEST_METHOD']])) {
|
||||
throw new RouteNotFoundException('Unknown HTTP method');
|
||||
}
|
||||
if ($this->url !== null) {
|
||||
if ($this->basePath === '' || PathHelper::startsWith($this->url, $this->basePath)) {
|
||||
foreach ($this->routes[$_SERVER['REQUEST_METHOD']] as $route) {
|
||||
if ($route->matches($this->url)) {
|
||||
return $route->call($di);
|
||||
|
48
src/Silex/Security/Security.php
Normal file
48
src/Silex/Security/Security.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Silex\Security;
|
||||
|
||||
use Silex\Gateway\UserGateway;
|
||||
use Silex\Model\User;
|
||||
|
||||
const USER = 'USER';
|
||||
|
||||
class Security
|
||||
{
|
||||
private array $session;
|
||||
private UserGateway $userGateway;
|
||||
private ?User $user = null;
|
||||
|
||||
public function __construct(UserGateway $userGateway, array $session)
|
||||
{
|
||||
$this->userGateway = $userGateway;
|
||||
$this->session = $session;
|
||||
}
|
||||
|
||||
public function initLogin(string $login, string $rawPassword): bool
|
||||
{
|
||||
$user = $this->userGateway->getByLogin($login);
|
||||
if ($user === null || !password_verify($rawPassword, $user->getPasswordHash())) {
|
||||
return false;
|
||||
}
|
||||
$this->session[USER] = $user->getId();
|
||||
$this->user = $user;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function logout()
|
||||
{
|
||||
$this->user = null;
|
||||
unset($this->session[USER]);
|
||||
}
|
||||
|
||||
public function getCurrentUser(): ?User
|
||||
{
|
||||
if (!empty($this->session[USER]) && $this->user === null) {
|
||||
$this->user = $this->userGateway->getById($this->session[USER]);
|
||||
}
|
||||
return $this->user;
|
||||
}
|
||||
}
|
@@ -2,9 +2,15 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title><?= $viewsArgs['title'] ?? 'Is it a blog?' ?></title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<?= $content ?>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<?= $content ?>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
30
views/login.php
Normal file
30
views/login.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php if ($params['fail']) : ?>
|
||||
<article class="message is-danger">
|
||||
<div class="message-header">
|
||||
<p>Auth failed</p>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
Login and/or password is invalid.
|
||||
</div>
|
||||
</article>
|
||||
<?php endif ?>
|
||||
<form action="<?= $_SERVER['REQUEST_URI'] ?>" method="post">
|
||||
<div class="field">
|
||||
<label class="label" for="login">Login</label>
|
||||
<div class="control">
|
||||
<input class="input" type="text" id="login" name="login">
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="password">Password</label>
|
||||
<div class="control">
|
||||
<input class="input" type="password" id="password" name="password">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<button class="button is-link">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
Reference in New Issue
Block a user