<?php
declare(strict_types=1);
namespace ParagonIE\Discretion\Middleware;
use ParagonIE\Discretion\Discretion;
use ParagonIE\Discretion\Exception\{
NotLoggedInException,
SecurityException
};
use ParagonIE\Discretion\MiddlewareInterface;
use Psr\Http\Message\{
RequestInterface,
ResponseInterface
};
use Slim\Http\Request;
use Slim\Http\Response;
/**
* Class UserAuthentication
* @package ParagonIE\Discretion\Middleware
*/
class UserAuthentication implements MiddlewareInterface
{
const PROPERTIES_TO_SET = ['authenticated'];
/**
* @return void
* @throws NotLoggedInException
*/
protected function assertLoggedIn()
{
if (empty($_SESSION['user_id'])) {
throw new NotLoggedInException('You are not logged in.');
}
}
/**
* Ensure all requests are authenticated.
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @param callable $next
* @return ResponseInterface
* @throws \Error
* @throws \Twig_Error_Loader
* @throws \Twig_Error_Runtime
* @throws \Twig_Error_Syntax
*/
public function __invoke(
RequestInterface $request,
ResponseInterface $response,
callable $next
): ResponseInterface {
try {
if ($request instanceof Request) {
$this->assertLoggedIn();
/** @var string $prop */
foreach (static::PROPERTIES_TO_SET as $prop) {
if (!\is_string($prop)) {
continue;
}
$request = $request->withAttribute($prop, true);
}
}
} catch (SecurityException $ex) {
return Discretion::redirect('/login');
} catch (\Throwable $ex) {
return Discretion::errorResponse('An unknown error has occurred.');
}
/** @var ResponseInterface $response */
$response = $next($request, $response);
if (!($response instanceof ResponseInterface)) {
throw new \TypeError('Response not an instance of ResponseInterface');
}
return $response;
}
}
|