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 MailAccountAdmin\Settings;
|
||||||
use Slim\Factory\AppFactory;
|
use Slim\Factory\AppFactory;
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
$settings = new Settings();
|
$settings = new Settings();
|
||||||
$container = Dependencies::createContainer($settings);
|
$container = Dependencies::createContainer($settings);
|
||||||
$app = AppFactory::createFromContainer($container);
|
$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;
|
namespace MailAccountAdmin;
|
||||||
|
|
||||||
use DI\Container;
|
use DI\Container;
|
||||||
use MailAccountAdmin\Login\LoginController;
|
use MailAccountAdmin\Frontend\Login\LoginController;
|
||||||
|
use MailAccountAdmin\Frontend\Dashboard\DashboardController;
|
||||||
use PDO;
|
use PDO;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
use Slim\Views\Twig;
|
use Slim\Views\Twig;
|
||||||
|
|
@ -47,13 +48,20 @@ class Dependencies
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Login, registration, authentication
|
// Login page
|
||||||
$container->set(LoginController::class, function (ContainerInterface $c) {
|
$container->set(LoginController::class, function (ContainerInterface $c) {
|
||||||
return new LoginController(
|
return new LoginController(
|
||||||
$c->get(self::TWIG)
|
$c->get(self::TWIG)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Dashboard
|
||||||
|
$container->set(DashboardController::class, function (ContainerInterface $c) {
|
||||||
|
return new DashboardController(
|
||||||
|
$c->get(self::TWIG)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return $container;
|
return $container;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace MailAccountAdmin\Login;
|
namespace MailAccountAdmin\Frontend\Dashboard;
|
||||||
|
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Slim\Views\Twig;
|
use Slim\Views\Twig;
|
||||||
|
|
||||||
class LoginController
|
class DashboardController
|
||||||
{
|
{
|
||||||
/** @var Twig */
|
/** @var Twig */
|
||||||
private $view;
|
private $view;
|
||||||
|
|
@ -17,11 +17,12 @@ class LoginController
|
||||||
$this->view = $view;
|
$this->view = $view;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function showLoginPage(Request $request, Response $response): Response
|
public function showDashboard(Request $request, Response $response): Response
|
||||||
{
|
{
|
||||||
$renderData = [
|
$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;
|
namespace MailAccountAdmin;
|
||||||
|
|
||||||
|
use MailAccountAdmin\Auth\AuthMiddleware;
|
||||||
use Slim\App;
|
use Slim\App;
|
||||||
use Slim\Views\TwigMiddleware;
|
use Slim\Views\TwigMiddleware;
|
||||||
|
|
||||||
|
|
@ -13,6 +14,7 @@ class Middlewares
|
||||||
$displayErrorDetails = $settings->isDebugMode();
|
$displayErrorDetails = $settings->isDebugMode();
|
||||||
|
|
||||||
$app->addErrorMiddleware($displayErrorDetails, true, true);
|
$app->addErrorMiddleware($displayErrorDetails, true, true);
|
||||||
|
$app->add(new AuthMiddleware());
|
||||||
$app->add(TwigMiddleware::createFromContainer($app));
|
$app->add(TwigMiddleware::createFromContainer($app));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,20 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace MailAccountAdmin;
|
namespace MailAccountAdmin;
|
||||||
|
|
||||||
use MailAccountAdmin\Login\LoginController;
|
use MailAccountAdmin\Frontend\Dashboard\DashboardController;
|
||||||
|
use MailAccountAdmin\Frontend\Login\LoginController;
|
||||||
use Slim\App;
|
use Slim\App;
|
||||||
|
|
||||||
class Routes
|
class Routes
|
||||||
{
|
{
|
||||||
public static function setRoutes(App $app): void
|
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