Skip to content

Commit

Permalink
[FEATURE] Add AuthenticationController and acceptance test for fixed …
Browse files Browse the repository at this point in the history
…admin login
  • Loading branch information
vertexvaar committed Oct 14, 2023
1 parent 55aa815 commit a8a8eee
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 20 deletions.
13 changes: 13 additions & 0 deletions config/routes.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use VerteXVaaR\BlueAuth\Controller\AuthenticationController;
use VerteXVaaR\BlueDist\Controller\Welcome;
use VerteXVaaR\BlueSprints\Routing\Middleware\RoutingMiddleware;

Expand All @@ -26,6 +27,14 @@
'controller' => Welcome::class,
'action' => 'listFruits',
],
'/login' => [
'controller' => AuthenticationController::class,
'action' => 'login',
],
'/logout' => [
'controller' => AuthenticationController::class,
'action' => 'logout',
],
'.*' => [
'controller' => Welcome::class,
'action' => 'index',
Expand Down Expand Up @@ -62,6 +71,10 @@
'controller' => Welcome::class,
'action' => 'createFruit',
],
'/login' => [
'controller' => AuthenticationController::class,
'action' => 'authenticate',
],
],
RoutingMiddleware::HTTP_METHOD_PUT => [],
RoutingMiddleware::HTTP_METHOD_DELETE => [],
Expand Down
79 changes: 79 additions & 0 deletions packages/blueauth/src/Controller/AuthenticationController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

declare(strict_types=1);

namespace VerteXVaaR\BlueAuth\Controller;

use Psr\Http\Message\ServerRequestInterface;
use RuntimeException;
use VerteXVaaR\BlueSprints\Environment\Config;
use VerteXVaaR\BlueSprints\Environment\Paths;
use VerteXVaaR\BlueSprints\Mvc\AbstractController;
use VerteXVaaR\BlueSprints\Mvc\Repository;
use VerteXVaaR\BlueSprints\Mvc\TemplateRenderer;
use VerteXVaaR\BlueSprints\Utility\Strings;

use function array_key_exists;
use function CoStack\Lib\concat_paths;
use function file_exists;
use function file_put_contents;
use function getenv;
use function json_encode;
use function mkdir;
use function setcookie;
use function unlink;

class AuthenticationController extends AbstractController
{
public function __construct(
Repository $repository,
TemplateRenderer $templateRenderer,
private readonly Paths $paths,
private readonly Config $config,
) {
parent::__construct($repository, $templateRenderer);
}

public function login(ServerRequestInterface $request): void
{
}

public function logout(ServerRequestInterface $request): void
{
$sessionIdentifier = $request->getAttribute('session');
if ($sessionIdentifier) {
$sessionFile = concat_paths(getenv('VXVR_BS_ROOT'), $this->paths->database, 'auth', $sessionIdentifier);
if (file_exists($sessionFile)) {
unlink($sessionFile);
}
setcookie($this->config->cookieAuthName ?: 'bluesprints_auth', '', -1, '/');
}
$this->redirect('/');
}

public function authenticate(ServerRequestInterface $request): void
{
$this->renderTemplate = false;
$body = $request->getParsedBody();
if (array_key_exists('username', $body) && array_key_exists('password', $body)) {
$username = $body['username'];
$password = $body['password'];
if ($username === 'admin' && $password === 'password') {
$path = concat_paths(getenv('VXVR_BS_ROOT'), $this->paths->database, 'auth');
$sessionIdentifier = Strings::generateUuid();
$session = [
'id' => $sessionIdentifier,
'username' => $username,
'authenticated' => true,
];
if (!mkdir($path, $this->config->folderPermissions, true) && !is_dir($path)) {
throw new RuntimeException(sprintf('Directory "%s" was not created', $path));
}
file_put_contents(concat_paths($path, $sessionIdentifier), json_encode($session));
setcookie($this->config->cookieAuthName ?: 'bluesprints_auth', $sessionIdentifier);
$this->redirect('/');
}
}
$this->redirect('/login');
}
}
10 changes: 7 additions & 3 deletions packages/blueauth/src/Middleware/AuthenticationMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

use function CoStack\Lib\concat_paths;
use function file_exists;
use function file_get_contents;
use function getenv;
use function json_decode;

readonly class AuthenticationMiddleware implements MiddlewareInterface
{
Expand All @@ -28,14 +31,14 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
$username = null;

$cookies = $request->getCookieParams();
$cookieAuthName = $this->config->cookieAuthName ?: 'bluedist_auth';
$cookieAuthName = $this->config->cookieAuthName ?: 'bluesprints_auth';
$authCookie = $cookies[$cookieAuthName] ?? null;

if (null !== $authCookie) {
$authPath = concat_paths($this->paths->database, 'auth');
$authPath = concat_paths(getenv('VXVR_BS_ROOT'), $this->paths->database, 'auth');
$cookieFile = concat_paths($authPath, $authCookie);
if (file_exists($cookieFile)) {
$sessionValues = require $cookieFile;
$sessionValues = json_decode(file_get_contents($cookieFile), true);
if ($sessionValues['authenticated'] ?? false) {
$authenticated = true;
$username = $sessionValues['username'] ?? null;
Expand All @@ -45,6 +48,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface

$request = $request->withAttribute('authenticated', $authenticated);
$request = $request->withAttribute('username', $username);
$request = $request->withAttribute('session', $authCookie);

return $handler->handle($request);
}
Expand Down
23 changes: 7 additions & 16 deletions packages/bluedebug/src/Middleware/DebugToolbarMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,25 @@
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use VerteXVaaR\BlueFluid\Mvc\FluidTemplateRenderer;
use VerteXVaaR\BlueSprints\Environment\Paths;

use function getenv;
use function strlen;
use function substr;
use VerteXVaaR\BlueSprints\Mvc\TemplateRenderer;

readonly class DebugToolbarMiddleware implements MiddlewareInterface
{

public function __construct()
public function __construct(private TemplateRenderer $templateRenderer)
{
}

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = $handler->handle($request);

$viewPath = dirname(__DIR__, 2) . '/view';
$viewPath = substr($viewPath, strlen(getenv('VXVR_BS_ROOT')));
$paths = new Paths('', '', '', '', '', $viewPath, '');
$templateRenderer = new FluidTemplateRenderer($paths);
$templateRenderer->setRouteConfiguration(['controller' => 'DebugToolbarMiddleware']);
$this->templateRenderer->setRouteConfiguration(['controller' => 'DebugToolbarMiddleware']);

$templateRenderer->setVariable('route', $request->getAttribute('route'));
$templateRenderer->setVariable('authenticated', $request->getAttribute('authenticated'));
$templateRenderer->setVariable('username', $request->getAttribute('username'));
$contents = $templateRenderer->render('DebugToolbar');
$this->templateRenderer->setVariable('route', $request->getAttribute('route'));
$this->templateRenderer->setVariable('authenticated', $request->getAttribute('authenticated'));
$this->templateRenderer->setVariable('username', $request->getAttribute('username'));
$contents = $this->templateRenderer->render('DebugToolbar');

$body = $response->getBody();
$body->seek($body->getSize());
Expand Down
2 changes: 1 addition & 1 deletion packages/bluesprints/src/Mvc/AbstractController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ abstract class AbstractController implements Controller
/**
* @var bool Indicates if the template should be rendered after the action has been called
*/
private bool $renderTemplate = true;
protected bool $renderTemplate = true;

public function __construct(
protected readonly Repository $repository,
Expand Down
42 changes: 42 additions & 0 deletions tests/acceptance/LoginCest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace acceptance;

use VerteXVaaR\BlueDistTest\AcceptanceTester;

use function ini_get;

class LoginCest
{

public function _before(AcceptanceTester $I)
{
}

// tests
public function loginAndLogout(AcceptanceTester $I)
{
$I->amOnPage('/');

if (ini_get('xdebug.mode') === 'debug') {
$I->setCookie('XDEBUG_SESSION', 'XDEBUG_ECLIPSE');
}

$I->see('User (anonymous session)');

$I->amOnPage('/login');
$I->submitForm('#login', [
'username' => 'admin',
'password' => 'password'
]);
// Requires bluesprints debug package
$I->see('User (authenticated): admin');

$I->amOnPage('/logout');

// Requires bluesprints debug package
$I->see('User (anonymous session)');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>

<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" lang="en">
<head>
<meta charset="utf-8">
<title>{pageTitle}</title>
</head>

<body>
<f:render section="Content"/>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Html"/>

<f:section name="Content">
<section>
<h1>Login</h1>
<form method="post" action="/login" id="login">
<table>
<tr>
<td>
<label>Username
<input type="text" name="username"/>
</label>
</td>
<td>
<label>Password
<input type="password" name="password"/>
</label>
</td>
<td>
<button type="submit">Login</button>
</td>
</tr>
</table>
</form>
</section>
</f:section>
</html>

0 comments on commit a8a8eee

Please sign in to comment.