From b4f9d31c2e2daebeb9f8413fcb0655057c51d173 Mon Sep 17 00:00:00 2001 From: clfreville2 Date: Tue, 22 Nov 2022 09:30:43 +0100 Subject: [PATCH] =?UTF-8?q?Permet=20=C3=A0=20l'utilisateur=20de=20se=20con?= =?UTF-8?q?necter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.php | 11 ++--- src/Silex/Controller/SecurityController.php | 27 ++++++++++++ src/Silex/DI/DI.php | 33 ++++++++++++++ src/Silex/Gateway/UserGateway.php | 36 ++++++++++++++++ src/Silex/Http/HttpResponse.php | 5 +++ src/Silex/Model/User.php | 41 ++++++++++++++++++ src/Silex/Router/PathHelper.php | 5 +++ src/Silex/Router/Router.php | 36 +++++++++++----- src/Silex/Security/Security.php | 48 +++++++++++++++++++++ views/layout.php | 10 ++++- views/login.php | 30 +++++++++++++ 11 files changed, 265 insertions(+), 17 deletions(-) create mode 100644 src/Silex/Controller/SecurityController.php create mode 100644 src/Silex/Gateway/UserGateway.php create mode 100644 src/Silex/Model/User.php create mode 100644 src/Silex/Security/Security.php create mode 100644 views/login.php diff --git a/public/index.php b/public/index.php index f956b2f..291addd 100644 --- a/public/index.php +++ b/public/index.php @@ -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\/(?[\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\/(?[\w-]+)$/', [$user, 'viewPost']); +$router->match('/^login$/', [$security, 'login']); +$router->run(new \Silex\DI\DI($router))->render(__DIR__ . '/../' . VIEW_PATH); diff --git a/src/Silex/Controller/SecurityController.php b/src/Silex/Controller/SecurityController.php new file mode 100644 index 0000000..177008b --- /dev/null +++ b/src/Silex/Controller/SecurityController.php @@ -0,0 +1,27 @@ +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]); + } +} \ No newline at end of file diff --git a/src/Silex/DI/DI.php b/src/Silex/DI/DI.php index fde5367..2de5880 100644 --- a/src/Silex/DI/DI.php +++ b/src/Silex/DI/DI.php @@ -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) { diff --git a/src/Silex/Gateway/UserGateway.php b/src/Silex/Gateway/UserGateway.php new file mode 100644 index 0000000..1bb3551 --- /dev/null +++ b/src/Silex/Gateway/UserGateway.php @@ -0,0 +1,36 @@ +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; + } +} diff --git a/src/Silex/Http/HttpResponse.php b/src/Silex/Http/HttpResponse.php index 7511c01..0342821 100644 --- a/src/Silex/Http/HttpResponse.php +++ b/src/Silex/Http/HttpResponse.php @@ -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; diff --git a/src/Silex/Model/User.php b/src/Silex/Model/User.php new file mode 100644 index 0000000..c89f60a --- /dev/null +++ b/src/Silex/Model/User.php @@ -0,0 +1,41 @@ +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; + } +} diff --git a/src/Silex/Router/PathHelper.php b/src/Silex/Router/PathHelper.php index 820d1bb..a9acf68 100644 --- a/src/Silex/Router/PathHelper.php +++ b/src/Silex/Router/PathHelper.php @@ -14,4 +14,9 @@ final class PathHelper } return $str; } + + public static function startsWith(string $haystack, string $needle): bool + { + return strpos($haystack, $needle) === 0; + } } diff --git a/src/Silex/Router/Router.php b/src/Silex/Router/Router.php index 2475084..23c38e0 100644 --- a/src/Silex/Router/Router.php +++ b/src/Silex/Router/Router.php @@ -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); + } + + 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(string $method, string $path, $callable): self + 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); diff --git a/src/Silex/Security/Security.php b/src/Silex/Security/Security.php new file mode 100644 index 0000000..eabca7c --- /dev/null +++ b/src/Silex/Security/Security.php @@ -0,0 +1,48 @@ +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; + } +} diff --git a/views/layout.php b/views/layout.php index 02b8bdb..54a1bb8 100644 --- a/views/layout.php +++ b/views/layout.php @@ -2,9 +2,15 @@ + <?= $viewsArgs['title'] ?? 'Is it a blog?' ?> + - +
+
+ +
+
- \ No newline at end of file + diff --git a/views/login.php b/views/login.php new file mode 100644 index 0000000..71e625a --- /dev/null +++ b/views/login.php @@ -0,0 +1,30 @@ + +
+
+

Auth failed

+
+
+ Login and/or password is invalid. +
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+
+ +
+
+