Implement basic login function; add basic styling
This commit is contained in:
parent
2bb7ea54a2
commit
8be7988d97
|
|
@ -9,6 +9,8 @@ use MailAccountAdmin\Routes;
|
|||
use MailAccountAdmin\Settings;
|
||||
use Slim\Factory\AppFactory;
|
||||
|
||||
session_start();
|
||||
|
||||
$settings = new Settings();
|
||||
$container = Dependencies::createContainer($settings);
|
||||
$app = AppFactory::createFromContainer($container);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
html, body {
|
||||
max-width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
/* --- Header --- */
|
||||
header {
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
/* --- Login page --- */
|
||||
main.login_page {
|
||||
margin: 2em;
|
||||
padding: 1em;
|
||||
border: 1px gray solid;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
main.login_page h2 {
|
||||
margin: 0 0 0.5em 0;
|
||||
}
|
||||
|
||||
main.login_page table td {
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
/* --- Text and other styling --- */
|
||||
.error {
|
||||
background: #ff4444;
|
||||
width: 30em;
|
||||
margin: 1em 0;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0.2em 1em;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MailAccountAdmin\Auth;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Slim\Psr7\Response;
|
||||
|
||||
class AuthMiddleware implements MiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
$uri = $request->getUri();
|
||||
|
||||
// TODO: Lots of stuff. Session middleware, auth handler class, etc...
|
||||
if ($uri->getPath() !== '/login') {
|
||||
// Check authorization via session
|
||||
if (empty($_SESSION['username'])) {
|
||||
// Not logged in -> Redirect to /login
|
||||
$response = new Response();
|
||||
return $response
|
||||
->withHeader('Location', '/login')
|
||||
->withStatus(303);
|
||||
}
|
||||
}
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,8 @@ declare(strict_types=1);
|
|||
namespace MailAccountAdmin;
|
||||
|
||||
use DI\Container;
|
||||
use MailAccountAdmin\Login\LoginController;
|
||||
use MailAccountAdmin\Frontend\Login\LoginController;
|
||||
use MailAccountAdmin\Frontend\Dashboard\DashboardController;
|
||||
use PDO;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Slim\Views\Twig;
|
||||
|
|
@ -47,13 +48,20 @@ class Dependencies
|
|||
);
|
||||
});
|
||||
|
||||
// Login, registration, authentication
|
||||
// Login page
|
||||
$container->set(LoginController::class, function (ContainerInterface $c) {
|
||||
return new LoginController(
|
||||
$c->get(self::TWIG)
|
||||
);
|
||||
});
|
||||
|
||||
// Dashboard
|
||||
$container->set(DashboardController::class, function (ContainerInterface $c) {
|
||||
return new DashboardController(
|
||||
$c->get(self::TWIG)
|
||||
);
|
||||
});
|
||||
|
||||
return $container;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MailAccountAdmin\Login;
|
||||
namespace MailAccountAdmin\Frontend\Dashboard;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Slim\Views\Twig;
|
||||
|
||||
class LoginController
|
||||
class DashboardController
|
||||
{
|
||||
/** @var Twig */
|
||||
private $view;
|
||||
|
|
@ -17,11 +17,12 @@ class LoginController
|
|||
$this->view = $view;
|
||||
}
|
||||
|
||||
public function showLoginPage(Request $request, Response $response): Response
|
||||
public function showDashboard(Request $request, Response $response): Response
|
||||
{
|
||||
$renderData = [
|
||||
'username' => $_SESSION['username'],
|
||||
];
|
||||
|
||||
return $this->view->render($response, 'login.html', $renderData);
|
||||
return $this->view->render($response, 'dashboard.html.twig', $renderData);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MailAccountAdmin\Frontend\Login;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Slim\Exception\HttpBadRequestException;
|
||||
use Slim\Views\Twig;
|
||||
|
||||
class LoginController
|
||||
{
|
||||
/** @var Twig */
|
||||
private $view;
|
||||
|
||||
public function __construct(Twig $view)
|
||||
{
|
||||
$this->view = $view;
|
||||
}
|
||||
|
||||
public function showLoginPage(Request $request, Response $response): Response
|
||||
{
|
||||
if (!empty($_SESSION['username'])) {
|
||||
// Already logged in, redirect to dashboard
|
||||
return $response
|
||||
->withHeader('Location', '/')
|
||||
->withStatus(303);
|
||||
}
|
||||
|
||||
$renderData = [
|
||||
];
|
||||
|
||||
return $this->view->render($response, 'login.html.twig', $renderData);
|
||||
}
|
||||
|
||||
public function authenticateUser(Request $request, Response $response): Response
|
||||
{
|
||||
$params = (array)$request->getParsedBody();
|
||||
|
||||
if (empty($params['username']) || empty($params['password'])) {
|
||||
throw new HttpBadRequestException($request, 'Missing parameters');
|
||||
}
|
||||
|
||||
// TODO: only for testing, obviously
|
||||
if ($params['username'] === 'lexi' && $params['password'] === 'testpw') {
|
||||
$_SESSION['username'] = $params['username'];
|
||||
return $response
|
||||
->withHeader('Location', '/')
|
||||
->withStatus(303);
|
||||
} else {
|
||||
return $this->view->render($response, 'login.html.twig', ['error' => 'Wrong username or password!']);
|
||||
}
|
||||
}
|
||||
|
||||
public function logoutUser(Request $request, Response $response): Response
|
||||
{
|
||||
session_destroy();
|
||||
|
||||
return $response
|
||||
->withHeader('Location', '/login')
|
||||
->withStatus(303);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace MailAccountAdmin;
|
||||
|
||||
use MailAccountAdmin\Auth\AuthMiddleware;
|
||||
use Slim\App;
|
||||
use Slim\Views\TwigMiddleware;
|
||||
|
||||
|
|
@ -13,6 +14,7 @@ class Middlewares
|
|||
$displayErrorDetails = $settings->isDebugMode();
|
||||
|
||||
$app->addErrorMiddleware($displayErrorDetails, true, true);
|
||||
$app->add(new AuthMiddleware());
|
||||
$app->add(TwigMiddleware::createFromContainer($app));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,20 @@ declare(strict_types=1);
|
|||
|
||||
namespace MailAccountAdmin;
|
||||
|
||||
use MailAccountAdmin\Login\LoginController;
|
||||
use MailAccountAdmin\Frontend\Dashboard\DashboardController;
|
||||
use MailAccountAdmin\Frontend\Login\LoginController;
|
||||
use Slim\App;
|
||||
|
||||
class Routes
|
||||
{
|
||||
public static function setRoutes(App $app): void
|
||||
{
|
||||
$app->get('/', LoginController::class . ':showLoginPage');
|
||||
// Login
|
||||
$app->get('/login', LoginController::class . ':showLoginPage');
|
||||
$app->post('/login', LoginController::class . ':authenticateUser');
|
||||
$app->get('/logout', LoginController::class . ':logoutUser');
|
||||
|
||||
// Dashboard
|
||||
$app->get('/', DashboardController::class . ':showDashboard');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{% block title %}Untitled page{% endblock %} - MailAccountAdmin</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>MailAccountAdmin</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
{% block content %}
|
||||
Nothing to see here...
|
||||
{% endblock %}
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block title %}Dashboard{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Dashboard</h2>
|
||||
|
||||
<p>Hello, {{ username }}!</p>
|
||||
|
||||
<a href="/logout">Logout.</a>
|
||||
{% endblock %}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>MailAccountAdmin</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!-- <link rel="stylesheet" href=""> -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>MailAccountAdmin - Login</h1>
|
||||
|
||||
<b>Hello.</b>
|
||||
|
||||
<!-- <script src="" async defer></script> -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Login - MailAccountAdmin</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>MailAccountAdmin</h1>
|
||||
</header>
|
||||
|
||||
<main class="login_page">
|
||||
<h2>Login</h2>
|
||||
|
||||
<form action="/login" method="POST">
|
||||
{% if error is defined %}
|
||||
<div class="error">{{ error }}</div>
|
||||
{% endif %}
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><label for="username">Username</label></td>
|
||||
<td><input type="text" id="username" name="username"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="password">Password</label></td>
|
||||
<td><input type="password" id="password" name="password"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><button type="submit">Login</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue