Skip to content

Commit

Permalink
Merge pull request #490 from leepeuker/add-web-authentication-middleware
Browse files Browse the repository at this point in the history
Added middleware
  • Loading branch information
leepeuker authored Sep 7, 2023
2 parents 7c4c3ef + 4af840f commit 1821f97
Show file tree
Hide file tree
Showing 35 changed files with 441 additions and 554 deletions.
1 change: 1 addition & 0 deletions bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
\Movary\HttpController\Web\JobController::class => DI\factory([Factory::class, 'createJobController']),
\Movary\HttpController\Web\LandingPageController::class => DI\factory([Factory::class, 'createLandingPageController']),
\Movary\HttpController\Web\SettingsController::class => DI\factory([Factory::class, 'createSettingsController']),
\Movary\HttpController\Web\Middleware\ServerHasRegistrationEnabled::class => DI\factory([Factory::class, 'createMiddlewareServerHasRegistrationEnabled']),
\Movary\ValueObject\Http\Request::class => DI\factory([Factory::class, 'createCurrentHttpRequest']),
\Movary\Command\CreatePublicStorageLink::class => DI\factory([Factory::class, 'createCreatePublicStorageLink']),
\Movary\Command\DatabaseMigrationStatus::class => DI\factory([Factory::class, 'createDatabaseMigrationStatusCommand']),
Expand Down
13 changes: 11 additions & 2 deletions public/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

try {
$dispatcher = FastRoute\simpleDispatcher(
require(__DIR__ . '/../settings/routes.php')
require(__DIR__ . '/../settings/routes.php'),
);

$uri = $_SERVER['REQUEST_URI'];
Expand All @@ -34,9 +34,18 @@
$response = Response::createMethodNotAllowed();
break;
case FastRoute\Dispatcher::FOUND:
$handler = $routeInfo[1];
$handler = $routeInfo[1]['handler'];
$httpRequest->addRouteParameters($routeInfo[2]);

foreach ($routeInfo[1]['middleware'] as $middleware) {
$middlewareResponse = $container->call($middleware, [$httpRequest]);

if ($middlewareResponse instanceof Response) {
$response = $middlewareResponse;
break 2;
}
}

$response = $container->call($handler, [$httpRequest]);
break;
default:
Expand Down
255 changes: 141 additions & 114 deletions settings/routes.php

Large diffs are not rendered by default.

40 changes: 22 additions & 18 deletions src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Movary\Domain\User\Service\TwoFactorAuthenticationApi;
use Movary\Domain\User\UserApi;
use Movary\HttpController\Api\OpenApiController;
use Movary\HttpController\Middleware;
use Movary\HttpController\Web\CreateUserController;
use Movary\HttpController\Web\JobController;
use Movary\HttpController\Web\LandingPageController;
Expand Down Expand Up @@ -97,14 +98,13 @@ public static function createCreatePublicStorageLink(ContainerInterface $contain
);
}

public static function createCreateUserController(ContainerInterface $container, Config $config) : CreateUserController
public static function createCreateUserController(ContainerInterface $container) : CreateUserController
{
return new CreateUserController(
$container->get(Twig\Environment::class),
$container->get(Authentication::class),
$container->get(UserApi::class),
$container->get(SessionWrapper::class),
$config->getAsBool('ENABLE_REGISTRATION', false),
);
}

Expand Down Expand Up @@ -177,15 +177,6 @@ public static function createExportService(ContainerInterface $container) : Expo
);
}

public static function createOpenApiController(ContainerInterface $container) : OpenApiController
{
return new OpenApiController(
$container->get(File::class),
$container->get(ServerSettings::class),
self::createDirectoryDocs(),
);
}

public static function createHttpClient() : ClientInterface
{
return new GuzzleHttp\Client(['timeout' => 4]);
Expand All @@ -208,7 +199,6 @@ public static function createJobController(ContainerInterface $container) : JobC
return new JobController(
$container->get(Authentication::class),
$container->get(JobQueueApi::class),
$container->get(UserApi::class),
$container->get(LetterboxdCsvValidator::class),
$container->get(SessionWrapper::class),
self::createDirectoryStorageApp()
Expand All @@ -227,8 +217,6 @@ public static function createLandingPageController(ContainerInterface $container
{
return new LandingPageController(
$container->get(Twig\Environment::class),
$container->get(Authentication::class),
$container->get(UserApi::class),
$container->get(SessionWrapper::class),
$config->getAsBool('ENABLE_REGISTRATION', false),
$config->getAsStringNullable('DEFAULT_LOGIN_EMAIL'),
Expand Down Expand Up @@ -262,6 +250,22 @@ public static function createLogger(ContainerInterface $container, Config $confi
return $logger;
}

public static function createMiddlewareServerHasRegistrationEnabled(Config $config) : HttpController\Web\Middleware\ServerHasRegistrationEnabled
{
return new HttpController\Web\Middleware\ServerHasRegistrationEnabled(
$config->getAsBool('ENABLE_REGISTRATION', false)
);
}

public static function createOpenApiController(ContainerInterface $container) : OpenApiController
{
return new OpenApiController(
$container->get(File::class),
$container->get(ServerSettings::class),
self::createDirectoryDocs(),
);
}

public static function createSettingsController(ContainerInterface $container, Config $config) : SettingsController
{
return new SettingsController(
Expand Down Expand Up @@ -374,14 +378,14 @@ private static function createDirectoryAppRoot() : string
return substr(__DIR__, 0, -strlen(self::SRC_DIRECTORY_NAME));
}

private static function createDirectoryStorage() : string
private static function createDirectoryDocs() : string
{
return self::createDirectoryAppRoot() . 'storage/';
return self::createDirectoryAppRoot() . 'docs/';
}

private static function createDirectoryDocs() : string
private static function createDirectoryStorage() : string
{
return self::createDirectoryAppRoot() . 'docs/';
return self::createDirectoryAppRoot() . 'storage/';
}

private static function createDirectoryStorageApp() : string
Expand Down
8 changes: 0 additions & 8 deletions src/HttpController/Web/AuthenticationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,6 @@ public function logout() : Response

public function renderLoginPage() : Response
{
if ($this->authenticationService->isUserAuthenticated() === true) {
return Response::create(
StatusCode::createSeeOther(),
null,
[Header::createLocation('/')],
);
}

$failedLogin = $this->sessionWrapper->has('failedLogin');
$this->sessionWrapper->unset('failedLogin');

Expand Down
18 changes: 0 additions & 18 deletions src/HttpController/Web/CreateUserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,13 @@ public function __construct(
private readonly Authentication $authenticationService,
private readonly UserApi $userApi,
private readonly SessionWrapper $sessionWrapper,
private readonly bool $registrationEnabled,
) {
}

// phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
public function createUser(Request $request) : Response
{
if ($this->authenticationService->isUserAuthenticated() === true) {
return Response::createSeeOther('/');
}

$hasUsers = $this->userApi->hasUsers();

if ($hasUsers === true && $this->registrationEnabled === false) {
return Response::createSeeOther('/');
}

$postParameters = $request->getPostParameters();

$email = empty($postParameters['email']) === true ? null : (string)$postParameters['email'];
Expand Down Expand Up @@ -92,16 +82,8 @@ public function createUser(Request $request) : Response

public function renderPage() : Response
{
if ($this->authenticationService->isUserAuthenticated() === true) {
return Response::createSeeOther('/');
}

$hasUsers = $this->userApi->hasUsers();

if ($hasUsers === true && $this->registrationEnabled === false) {
return Response::createSeeOther('/');
}

$errorPasswordTooShort = $this->sessionWrapper->find('errorPasswordTooShort');
$errorPasswordNotEqual = $this->sessionWrapper->find('errorPasswordNotEqual');
$errorUsernameInvalidFormat = $this->sessionWrapper->find('errorUsernameInvalidFormat');
Expand Down
10 changes: 0 additions & 10 deletions src/HttpController/Web/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,6 @@ public function __construct(
) {
}

public function redirectToDashboard(Request $request) : Response
{
$user = $this->userPageAuthorizationChecker->findUserIfCurrentVisitorIsAllowedToSeeUser((string)$request->getRouteParameters()['username']);
if ($user === null) {
return Response::createSeeOther('/');
}

return Response::createSeeOther('/users/' . $user->getName() . '/dashboard');
}

public function render(Request $request) : Response
{
$userId = $this->userPageAuthorizationChecker->findUserIdIfCurrentVisitorIsAllowedToSeeUser((string)$request->getRouteParameters()['username']);
Expand Down
8 changes: 0 additions & 8 deletions src/HttpController/Web/EmbyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ public function __construct(

public function deleteEmbyWebhookUrl() : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createSeeOther('/');
}

$this->userApi->deleteEmbyWebhookId($this->authenticationService->getCurrentUserId());

return Response::createOk();
Expand All @@ -53,10 +49,6 @@ public function handleEmbyWebhook(Request $request) : Response

public function regenerateEmbyWebhookUrl() : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createSeeOther('/');
}

$webhookId = $this->userApi->regenerateEmbyWebhookId($this->authenticationService->getCurrentUserId());

return Response::createJson(Json::encode(['url' => $this->webhookUrlBuilder->buildEmbyWebhookUrl($webhookId)]));
Expand Down
4 changes: 0 additions & 4 deletions src/HttpController/Web/ExportController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ public function __construct(

public function getCsvExport(Request $request) : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createSeeOther('/login');
}

$userId = $this->authenticationService->getCurrentUserId();

$exportType = $request->getRouteParameters()['exportType'] ?? null;
Expand Down
12 changes: 0 additions & 12 deletions src/HttpController/Web/HistoryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ public function __construct(

public function createHistoryEntry(Request $request) : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createForbidden();
}

$userId = $this->authenticationService->getCurrentUserId();

if ($this->userApi->fetchUser($userId)->getName() !== $request->getRouteParameters()['username']) {
Expand All @@ -61,10 +57,6 @@ public function createHistoryEntry(Request $request) : Response

public function deleteHistoryEntry(Request $request) : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createForbidden();
}

$userId = $this->authenticationService->getCurrentUserId();

if ($this->userApi->fetchUser($userId)->getName() !== $request->getRouteParameters()['username']) {
Expand All @@ -83,10 +75,6 @@ public function deleteHistoryEntry(Request $request) : Response

public function logMovie(Request $request) : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createSeeOther('/');
}

$userId = $this->authenticationService->getCurrentUserId();

$requestData = Json::decode($request->getBody());
Expand Down
4 changes: 0 additions & 4 deletions src/HttpController/Web/ImportController.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ public function __construct(

public function handleCsvImport(Request $request) : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createSeeOther('/login');
}

$userId = $this->authenticationService->getCurrentUserId();
$exportType = $request->getRouteParameters()['exportType'];
$fileParameters = $request->getFileParameters();
Expand Down
28 changes: 0 additions & 28 deletions src/HttpController/Web/JellyfinController.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ public function __construct(

public function authenticateJellyfinAccount(Request $request) : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createSeeOther('/');
}

$userId = $this->authenticationService->getCurrentUserId();

$username = Json::decode($request->getBody())['username'];
Expand Down Expand Up @@ -65,10 +61,6 @@ public function authenticateJellyfinAccount(Request $request) : Response

public function deleteJellyfinWebhookUrl() : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createSeeOther('/');
}

$this->userApi->deleteJellyfinWebhookId($this->authenticationService->getCurrentUserId());

return Response::createOk();
Expand All @@ -94,21 +86,13 @@ public function handleJellyfinWebhook(Request $request) : Response

public function regenerateJellyfinWebhookUrl() : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createSeeOther('/');
}

$webhookId = $this->userApi->regenerateJellyfinWebhookId($this->authenticationService->getCurrentUserId());

return Response::createJson(Json::encode(['url' => $this->webhookUrlBuilder->buildJellyfinWebhookUrl($webhookId)]));
}

public function removeJellyfinAuthentication() : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createSeeOther('/');
}

$userId = $this->authenticationService->getCurrentUserId();
$jellyfinAuthentication = $this->userApi->findJellyfinAuthentication($userId);

Expand All @@ -131,10 +115,6 @@ public function removeJellyfinAuthentication() : Response

public function saveJellyfinServerUrl(Request $request) : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createSeeOther('/');
}

$jellyfinServerUrl = Json::decode($request->getBody())['JellyfinServerUrl'];
$userId = $this->authenticationService->getCurrentUserId();

Expand All @@ -157,10 +137,6 @@ public function saveJellyfinServerUrl(Request $request) : Response

public function saveJellyfinSyncOptions(Request $request) : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createSeeOther('/');
}

$syncWatches = Json::decode($request->getBody())['syncWatches'];
$userId = $this->authenticationService->getCurrentUserId();

Expand All @@ -171,10 +147,6 @@ public function saveJellyfinSyncOptions(Request $request) : Response

public function verifyJellyfinServerUrl(Request $request) : Response
{
if ($this->authenticationService->isUserAuthenticated() === false) {
return Response::createSeeOther('/');
}

$jellyfinServerUrl = Url::createFromString(Json::decode($request->getBody())['jellyfinServerUrl']);
$jellyfinAuthentication = $this->userApi->findJellyfinAuthentication($this->authenticationService->getCurrentUserId());

Expand Down
Loading

0 comments on commit 1821f97

Please sign in to comment.