diff --git a/bootstrap.php b/bootstrap.php index bd3a081f..4cefe0f9 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -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']), diff --git a/public/index.php b/public/index.php index dbbc03aa..5d4d94a8 100644 --- a/public/index.php +++ b/public/index.php @@ -14,7 +14,7 @@ try { $dispatcher = FastRoute\simpleDispatcher( - require(__DIR__ . '/../settings/routes.php') + require(__DIR__ . '/../settings/routes.php'), ); $uri = $_SERVER['REQUEST_URI']; @@ -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: diff --git a/settings/routes.php b/settings/routes.php index 455aba46..10e16ab9 100644 --- a/settings/routes.php +++ b/settings/routes.php @@ -1,147 +1,174 @@ addGroup('', fn(FastRoute\RouteCollector $routeCollector) => addWebRoutes($routeCollector)); - $routeCollector->addGroup('/api', fn(FastRoute\RouteCollector $routeCollector) => addApiRoutes($routeCollector)); +return function (FastRoute\RouteCollector $routeCollector) { + $routerService = new RouterService(); + + $routeCollector->addGroup('', fn($routeCollector) => addWebRoutes($routerService, $routeCollector)); + $routeCollector->addGroup('/api', fn($routeCollector) => addApiRoutes($routerService, $routeCollector)); }; -function addWebRoutes(FastRoute\RouteCollector $routeCollector) : void +function addWebRoutes(RouterService $routerService, FastRoute\RouteCollector $routeCollector) : void { - $routeCollector->addRoute('GET', '/', [Web\LandingPageController::class, 'render']); - $routeCollector->addRoute('POST', '/login', [Web\AuthenticationController::class, 'login']); - $routeCollector->addRoute('GET', '/login', [Web\AuthenticationController::class, 'renderLoginPage']); - $routeCollector->addRoute('POST', '/verify-totp', [Web\TwoFactorAuthenticationController::class, 'verifyTotp']); - $routeCollector->addRoute('GET', '/logout', [Web\AuthenticationController::class, 'logout']); - $routeCollector->addRoute('POST', '/create-user', [Web\CreateUserController::class, 'createUser']); - $routeCollector->addRoute('GET', '/create-user', [Web\CreateUserController::class, 'renderPage']); - $routeCollector->addRoute('GET', '/docs/api', [Web\OpenApiController::class, 'renderPage']); + $routes = RouteList::create(); + + $routes->add('GET', '/', [Web\LandingPageController::class, 'render'], [Web\Middleware\UserIsUnauthenticated::class, Web\Middleware\ServerHasNoUsers::class]); + $routes->add('GET', '/login', [Web\AuthenticationController::class, 'renderLoginPage'], [Web\Middleware\UserIsUnauthenticated::class]); + $routes->add('POST', '/login', [Web\AuthenticationController::class, 'login']); + $routes->add('POST', '/verify-totp', [Web\TwoFactorAuthenticationController::class, 'verifyTotp'], [Web\Middleware\UserIsUnauthenticated::class]); + $routes->add('GET', '/logout', [Web\AuthenticationController::class, 'logout']); + $routes->add('POST', '/create-user', [Web\CreateUserController::class, 'createUser'], [ + Web\Middleware\UserIsUnauthenticated::class, + Web\Middleware\ServerHasUsers::class, + Web\Middleware\ServerHasRegistrationEnabled::class + ]); + $routes->add('GET', '/create-user', [Web\CreateUserController::class, 'renderPage'], [ + Web\Middleware\UserIsUnauthenticated::class, + Web\Middleware\ServerHasUsers::class, + Web\Middleware\ServerHasRegistrationEnabled::class + ]); + $routes->add('GET', '/docs/api', [Web\OpenApiController::class, 'renderPage']); ##################### # Webhook listeners # ##################### - $routeCollector->addRoute('POST', '/plex/{id:.+}', [Web\PlexController::class, 'handlePlexWebhook']); - $routeCollector->addRoute('POST', '/jellyfin/{id:.+}', [Web\JellyfinController::class, 'handleJellyfinWebhook']); - $routeCollector->addRoute('POST', '/emby/{id:.+}', [Web\EmbyController::class, 'handleEmbyWebhook']); + $routes->add('POST', '/plex/{id:.+}', [Web\PlexController::class, 'handlePlexWebhook']); + $routes->add('POST', '/jellyfin/{id:.+}', [Web\JellyfinController::class, 'handleJellyfinWebhook']); + $routes->add('POST', '/emby/{id:.+}', [Web\EmbyController::class, 'handleEmbyWebhook']); ############# # Job Queue # ############# - $routeCollector->addRoute('GET', '/jobs', [Web\JobController::class, 'getJobs']); - $routeCollector->addRoute('GET', '/job-queue/purge-processed', [Web\JobController::class, 'purgeProcessedJobs']); - $routeCollector->addRoute('GET', '/job-queue/purge-all', [Web\JobController::class, 'purgeAllJobs']); - $routeCollector->addRoute('GET', '/jobs/schedule/trakt-history-sync', [Web\JobController::class, 'scheduleTraktHistorySync']); - $routeCollector->addRoute('GET', '/jobs/schedule/trakt-ratings-sync', [Web\JobController::class, 'scheduleTraktRatingsSync']); - $routeCollector->addRoute('POST', '/jobs/schedule/letterboxd-diary-sync', [Web\JobController::class, 'scheduleLetterboxdDiaryImport']); - $routeCollector->addRoute('POST', '/jobs/schedule/letterboxd-ratings-sync', [Web\JobController::class, 'scheduleLetterboxdRatingsImport']); - $routeCollector->addRoute('GET', '/jobs/schedule/plex-watchlist-sync', [Web\JobController::class, 'schedulePlexWatchlistImport']); - $routeCollector->addRoute('GET', '/jobs/schedule/jellyfin-import-history', [Web\JobController::class, 'scheduleJellyfinImportHistory']); - $routeCollector->addRoute('GET', '/jobs/schedule/jellyfin-export-history', [Web\JobController::class, 'scheduleJellyfinExportHistory']); + $routes->add('GET', '/jobs', [Web\JobController::class, 'getJobs'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/job-queue/purge-processed', [Web\JobController::class, 'purgeProcessedJobs'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/job-queue/purge-all', [Web\JobController::class, 'purgeAllJobs'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/jobs/schedule/trakt-history-sync', [Web\JobController::class, 'scheduleTraktHistorySync'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/jobs/schedule/trakt-ratings-sync', [Web\JobController::class, 'scheduleTraktRatingsSync'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/jobs/schedule/letterboxd-diary-sync', [Web\JobController::class, 'scheduleLetterboxdDiaryImport'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/jobs/schedule/letterboxd-ratings-sync', [Web\JobController::class, 'scheduleLetterboxdRatingsImport'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/jobs/schedule/plex-watchlist-sync', [Web\JobController::class, 'schedulePlexWatchlistImport'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/jobs/schedule/jellyfin-import-history', [Web\JobController::class, 'scheduleJellyfinImportHistory'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/jobs/schedule/jellyfin-export-history', [Web\JobController::class, 'scheduleJellyfinExportHistory'], [ + Web\Middleware\UserIsAuthenticated::class, + Web\Middleware\UserHasJellyfinToken::class + ]); ############ # Settings # ############ - $routeCollector->addRoute('GET', '/settings/account/general', [Web\SettingsController::class, 'renderGeneralAccountPage']); - $routeCollector->addRoute('GET', '/settings/account/general/api-token', [Web\SettingsController::class, 'getApiToken'],); - $routeCollector->addRoute('DELETE', '/settings/account/general/api-token', [Web\SettingsController::class, 'deleteApiToken'],); - $routeCollector->addRoute('PUT', '/settings/account/general/api-token', [Web\SettingsController::class, 'regenerateApiToken'],); - $routeCollector->addRoute('GET', '/settings/account/dashboard', [Web\SettingsController::class, 'renderDashboardAccountPage']); - $routeCollector->addRoute('GET', '/settings/account/security', [Web\SettingsController::class, 'renderSecurityAccountPage']); - $routeCollector->addRoute('GET', '/settings/account/data', [Web\SettingsController::class, 'renderDataAccountPage']); - $routeCollector->addRoute('GET', '/settings/server/general', [Web\SettingsController::class, 'renderServerGeneralPage']); - $routeCollector->addRoute('GET', '/settings/server/jobs', [Web\SettingsController::class, 'renderServerJobsPage']); - $routeCollector->addRoute('POST', '/settings/server/general', [Web\SettingsController::class, 'updateServerGeneral']); - $routeCollector->addRoute('GET', '/settings/server/users', [Web\SettingsController::class, 'renderServerUsersPage']); - $routeCollector->addRoute('GET', '/settings/server/email', [Web\SettingsController::class, 'renderServerEmailPage']); - $routeCollector->addRoute('POST', '/settings/server/email', [Web\SettingsController::class, 'updateServerEmail']); - $routeCollector->addRoute('POST', '/settings/server/email-test', [Web\SettingsController::class, 'sendTestEmail']); - $routeCollector->addRoute('POST', '/settings/account', [Web\SettingsController::class, 'updateGeneral']); - $routeCollector->addRoute('POST', '/settings/account/security/update-password', [Web\SettingsController::class, 'updatePassword']); - $routeCollector->addRoute('POST', '/settings/account/security/create-totp-uri', [Web\TwoFactorAuthenticationController::class, 'createTotpUri']); - $routeCollector->addRoute('POST', '/settings/account/security/disable-totp', [Web\TwoFactorAuthenticationController::class, 'disableTotp']); - $routeCollector->addRoute('POST', '/settings/account/security/enable-totp', [Web\TwoFactorAuthenticationController::class, 'enableTotp']); - $routeCollector->addRoute('GET', '/settings/account/export/csv/{exportType:.+}', [Web\ExportController::class, 'getCsvExport']); - $routeCollector->addRoute('POST', '/settings/account/import/csv/{exportType:.+}', [Web\ImportController::class, 'handleCsvImport']); - $routeCollector->addRoute('GET', '/settings/account/delete-ratings', [Web\SettingsController::class, 'deleteRatings']); - $routeCollector->addRoute('GET', '/settings/account/delete-history', [Web\SettingsController::class, 'deleteHistory']); - $routeCollector->addRoute('GET', '/settings/account/delete-account', [Web\SettingsController::class, 'deleteAccount']); - $routeCollector->addRoute('POST', '/settings/account/update-dashboard-rows', [Web\SettingsController::class, 'updateDashboardRows']); - $routeCollector->addRoute('POST', '/settings/account/reset-dashboard-rows', [Web\SettingsController::class, 'resetDashboardRows']); - $routeCollector->addRoute('GET', '/settings/integrations/trakt', [Web\SettingsController::class, 'renderTraktPage']); - $routeCollector->addRoute('POST', '/settings/trakt', [Web\SettingsController::class, 'updateTrakt']); - $routeCollector->addRoute('POST', '/settings/trakt/verify-credentials', [Web\SettingsController::class, 'traktVerifyCredentials']); - $routeCollector->addRoute('GET', '/settings/integrations/letterboxd', [Web\SettingsController::class, 'renderLetterboxdPage']); - $routeCollector->addRoute('GET', '/settings/letterboxd-export', [Web\SettingsController::class, 'generateLetterboxdExportData']); - $routeCollector->addRoute('GET', '/settings/integrations/plex', [Web\SettingsController::class, 'renderPlexPage']); - $routeCollector->addRoute('GET', '/settings/plex/logout', [Web\PlexController::class, 'removePlexAccessTokens']); - $routeCollector->addRoute('POST', '/settings/plex/server-url-save', [Web\PlexController::class, 'savePlexServerUrl']); - $routeCollector->addRoute('POST', '/settings/plex/server-url-verify', [Web\PlexController::class, 'verifyPlexServerUrl']); - $routeCollector->addRoute('GET', '/settings/plex/authentication-url', [Web\PlexController::class, 'generatePlexAuthenticationUrl']); - $routeCollector->addRoute('GET', '/settings/plex/callback', [Web\PlexController::class, 'processPlexCallback']); - $routeCollector->addRoute('POST', '/settings/plex', [Web\SettingsController::class, 'updatePlex']); - $routeCollector->addRoute('PUT', '/settings/plex/webhook', [Web\PlexController::class, 'regeneratePlexWebhookUrl']); - $routeCollector->addRoute('DELETE', '/settings/plex/webhook', [Web\PlexController::class, 'deletePlexWebhookUrl']); - $routeCollector->addRoute('GET', '/settings/integrations/jellyfin', [Web\SettingsController::class, 'renderJellyfinPage']); - $routeCollector->addRoute('POST', '/settings/jellyfin', [Web\SettingsController::class, 'updateJellyfin']); - $routeCollector->addRoute('POST', '/settings/jellyfin/sync', [Web\JellyfinController::class, 'saveJellyfinSyncOptions']); - $routeCollector->addRoute('POST', '/settings/jellyfin/authenticate', [Web\JellyfinController::class, 'authenticateJellyfinAccount']); - $routeCollector->addRoute('POST', '/settings/jellyfin/remove-authentication', [Web\JellyfinController::class, 'removeJellyfinAuthentication']); - $routeCollector->addRoute('POST', '/settings/jellyfin/server-url-save', [Web\JellyfinController::class, 'saveJellyfinServerUrl']); - $routeCollector->addRoute('POST', '/settings/jellyfin/server-url-verify', [Web\JellyfinController::class, 'verifyJellyfinServerUrl']); - $routeCollector->addRoute('GET', '/settings/jellyfin/webhook', [Web\JellyfinController::class, 'getJellyfinWebhookUrl']); - $routeCollector->addRoute('PUT', '/settings/jellyfin/webhook', [Web\JellyfinController::class, 'regenerateJellyfinWebhookUrl']); - $routeCollector->addRoute('DELETE', '/settings/jellyfin/webhook', [Web\JellyfinController::class, 'deleteJellyfinWebhookUrl']); - $routeCollector->addRoute('GET', '/settings/integrations/emby', [Web\SettingsController::class, 'renderEmbyPage']); - $routeCollector->addRoute('POST', '/settings/emby', [Web\SettingsController::class, 'updateEmby']); - $routeCollector->addRoute('GET', '/settings/emby/webhook', [Web\EmbyController::class, 'getEmbyWebhookUrl']); - $routeCollector->addRoute('PUT', '/settings/emby/webhook', [Web\EmbyController::class, 'regenerateEmbyWebhookUrl']); - $routeCollector->addRoute('DELETE', '/settings/emby/webhook', [Web\EmbyController::class, 'deleteEmbyWebhookUrl']); - $routeCollector->addRoute('GET', '/settings/app', [Web\SettingsController::class, 'renderAppPage']); - $routeCollector->addRoute('GET', '/settings/integrations/netflix', [Web\SettingsController::class, 'renderNetflixPage']); - $routeCollector->addRoute('POST', '/settings/netflix', [Web\NetflixController::class, 'matchNetflixActivityCsvWithTmdbMovies']); - $routeCollector->addRoute('POST', '/settings/netflix/import', [Web\NetflixController::class, 'importNetflixData']); - $routeCollector->addRoute('POST', '/settings/netflix/search', [Web\NetflixController::class, 'searchTmbd']); - $routeCollector->addRoute('GET', '/settings/users', [Web\UserController::class, 'fetchUsers']); - $routeCollector->addRoute('POST', '/settings/users', [Web\UserController::class, 'createUser']); - $routeCollector->addRoute('PUT', '/settings/users/{userId:\d+}', [Web\UserController::class, 'updateUser']); - $routeCollector->addRoute('DELETE', '/settings/users/{userId:\d+}', [Web\UserController::class, 'deleteUser']); + $routes->add('GET', '/settings/account/general', [Web\SettingsController::class, 'renderGeneralAccountPage'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/account/general/api-token', [Web\SettingsController::class, 'getApiToken'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('DELETE', '/settings/account/general/api-token', [Web\SettingsController::class, 'deleteApiToken'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('PUT', '/settings/account/general/api-token', [Web\SettingsController::class, 'regenerateApiToken'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/account/dashboard', [Web\SettingsController::class, 'renderDashboardAccountPage'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/account/security', [Web\SettingsController::class, 'renderSecurityAccountPage'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/account/data', [Web\SettingsController::class, 'renderDataAccountPage'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/server/general', [Web\SettingsController::class, 'renderServerGeneralPage'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/server/jobs', [Web\SettingsController::class, 'renderServerJobsPage'], [Web\Middleware\UserIsAuthenticated::class, Web\Middleware\UserIsAdmin::class]); + $routes->add('POST', '/settings/server/general', [Web\SettingsController::class, 'updateServerGeneral'], [ + Web\Middleware\UserIsAuthenticated::class, + Web\Middleware\UserIsAdmin::class + ]); + $routes->add('GET', '/settings/server/users', [Web\SettingsController::class, 'renderServerUsersPage'], [Web\Middleware\UserIsAuthenticated::class, Web\Middleware\UserIsAdmin::class]); + $routes->add('GET', '/settings/server/email', [Web\SettingsController::class, 'renderServerEmailPage'], [Web\Middleware\UserIsAuthenticated::class, Web\Middleware\UserIsAdmin::class]); + $routes->add('POST', '/settings/server/email', [Web\SettingsController::class, 'updateServerEmail'], [Web\Middleware\UserIsAuthenticated::class, Web\Middleware\UserIsAdmin::class]); + $routes->add('POST', '/settings/server/email-test', [Web\SettingsController::class, 'sendTestEmail'], [Web\Middleware\UserIsAuthenticated::class, Web\Middleware\UserIsAdmin::class]); + $routes->add('POST', '/settings/account', [Web\SettingsController::class, 'updateGeneral'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/account/security/update-password', [Web\SettingsController::class, 'updatePassword'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/account/security/create-totp-uri', [Web\TwoFactorAuthenticationController::class, 'createTotpUri'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/account/security/disable-totp', [Web\TwoFactorAuthenticationController::class, 'disableTotp'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/account/security/enable-totp', [Web\TwoFactorAuthenticationController::class, 'enableTotp'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/account/export/csv/{exportType:.+}', [Web\ExportController::class, 'getCsvExport'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/account/import/csv/{exportType:.+}', [Web\ImportController::class, 'handleCsvImport'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/account/delete-ratings', [Web\SettingsController::class, 'deleteRatings'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/account/delete-history', [Web\SettingsController::class, 'deleteHistory'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/account/delete-account', [Web\SettingsController::class, 'deleteAccount'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/account/update-dashboard-rows', [Web\SettingsController::class, 'updateDashboardRows'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/account/reset-dashboard-rows', [Web\SettingsController::class, 'resetDashboardRows'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/integrations/trakt', [Web\SettingsController::class, 'renderTraktPage'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/trakt', [Web\SettingsController::class, 'updateTrakt'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/trakt/verify-credentials', [Web\SettingsController::class, 'traktVerifyCredentials'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/integrations/letterboxd', [Web\SettingsController::class, 'renderLetterboxdPage'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/letterboxd-export', [Web\SettingsController::class, 'generateLetterboxdExportData'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/integrations/plex', [Web\SettingsController::class, 'renderPlexPage'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/plex/logout', [Web\PlexController::class, 'removePlexAccessTokens'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/plex/server-url-save', [Web\PlexController::class, 'savePlexServerUrl'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/plex/server-url-verify', [Web\PlexController::class, 'verifyPlexServerUrl'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/plex/authentication-url', [Web\PlexController::class, 'generatePlexAuthenticationUrl'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/plex/callback', [Web\PlexController::class, 'processPlexCallback'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/plex', [Web\SettingsController::class, 'updatePlex'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('PUT', '/settings/plex/webhook', [Web\PlexController::class, 'regeneratePlexWebhookUrl'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('DELETE', '/settings/plex/webhook', [Web\PlexController::class, 'deletePlexWebhookUrl'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/integrations/jellyfin', [Web\SettingsController::class, 'renderJellyfinPage'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/jellyfin', [Web\SettingsController::class, 'updateJellyfin'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/jellyfin/sync', [Web\JellyfinController::class, 'saveJellyfinSyncOptions'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/jellyfin/authenticate', [Web\JellyfinController::class, 'authenticateJellyfinAccount'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/jellyfin/remove-authentication', [Web\JellyfinController::class, 'removeJellyfinAuthentication'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/jellyfin/server-url-save', [Web\JellyfinController::class, 'saveJellyfinServerUrl'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/jellyfin/server-url-verify', [Web\JellyfinController::class, 'verifyJellyfinServerUrl'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/jellyfin/webhook', [Web\JellyfinController::class, 'getJellyfinWebhookUrl'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('PUT', '/settings/jellyfin/webhook', [Web\JellyfinController::class, 'regenerateJellyfinWebhookUrl'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('DELETE', '/settings/jellyfin/webhook', [Web\JellyfinController::class, 'deleteJellyfinWebhookUrl'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/integrations/emby', [Web\SettingsController::class, 'renderEmbyPage'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/emby', [Web\SettingsController::class, 'updateEmby'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/emby/webhook', [Web\EmbyController::class, 'getEmbyWebhookUrl']); + $routes->add('PUT', '/settings/emby/webhook', [Web\EmbyController::class, 'regenerateEmbyWebhookUrl'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('DELETE', '/settings/emby/webhook', [Web\EmbyController::class, 'deleteEmbyWebhookUrl'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/app', [Web\SettingsController::class, 'renderAppPage'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/integrations/netflix', [Web\SettingsController::class, 'renderNetflixPage'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/netflix', [Web\NetflixController::class, 'matchNetflixActivityCsvWithTmdbMovies'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/netflix/import', [Web\NetflixController::class, 'importNetflixData'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/settings/netflix/search', [Web\NetflixController::class, 'searchTmbd'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/settings/users', [Web\UserController::class, 'fetchUsers']); + $routes->add('POST', '/settings/users', [Web\UserController::class, 'createUser']); + $routes->add('PUT', '/settings/users/{userId:\d+}', [Web\UserController::class, 'updateUser'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('DELETE', '/settings/users/{userId:\d+}', [Web\UserController::class, 'deleteUser'], [Web\Middleware\UserIsAuthenticated::class]); ########## # Movies # ########## - $routeCollector->addRoute('GET', '/movies/{id:[0-9]+}/refresh-tmdb', [Web\Movie\MovieController::class, 'refreshTmdbData']); - $routeCollector->addRoute('GET', '/movies/{id:[0-9]+}/refresh-imdb', [Web\Movie\MovieController::class, 'refreshImdbRating']); - $routeCollector->addRoute('GET', '/movies/{id:[0-9]+}/watch-providers', [Web\Movie\MovieWatchProviderController::class, 'getWatchProviders']); - $routeCollector->addRoute('GET', '/movies/{id:[0-9]+}/add-watchlist', [Web\Movie\MovieWatchlistController::class, 'addToWatchlist']); - $routeCollector->addRoute('GET', '/movies/{id:[0-9]+}/remove-watchlist', [Web\Movie\MovieWatchlistController::class, 'removeFromWatchlist']); + $routes->add('GET', '/movies/{id:[0-9]+}/refresh-tmdb', [Web\Movie\MovieController::class, 'refreshTmdbData'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/movies/{id:[0-9]+}/refresh-imdb', [Web\Movie\MovieController::class, 'refreshImdbRating'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/movies/{id:[0-9]+}/watch-providers', [Web\Movie\MovieWatchProviderController::class, 'getWatchProviders']); + $routes->add('GET', '/movies/{id:[0-9]+}/add-watchlist', [Web\Movie\MovieWatchlistController::class, 'addToWatchlist'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/movies/{id:[0-9]+}/remove-watchlist', [Web\Movie\MovieWatchlistController::class, 'removeFromWatchlist'], [Web\Middleware\UserIsAuthenticated::class]); ############## # User media # ############## - $routeCollector->addRoute('GET', '/users/{username:[a-zA-Z0-9]+}/dashboard', [Web\DashboardController::class, 'render']); - $routeCollector->addRoute('GET', '/users/{username:[a-zA-Z0-9]+}/history', [Web\HistoryController::class, 'renderHistory']); - $routeCollector->addRoute('GET', '/users/{username:[a-zA-Z0-9]+}/watchlist', [Web\WatchlistController::class, 'renderWatchlist']); - $routeCollector->addRoute('GET', '/users/{username:[a-zA-Z0-9]+}/movies', [Web\MoviesController::class, 'renderPage']); - $routeCollector->addRoute('GET', '/users/{username:[a-zA-Z0-9]+}/actors', [Web\ActorsController::class, 'renderPage']); - $routeCollector->addRoute('GET', '/users/{username:[a-zA-Z0-9]+}/directors', [Web\DirectorsController::class, 'renderPage']); - $routeCollector->addRoute('GET', '/users/{username:[a-zA-Z0-9]+}/movies/{id:\d+}', [Web\Movie\MovieController::class, 'renderPage']); - $routeCollector->addRoute('GET', '/users/{username:[a-zA-Z0-9]+}/persons/{id:\d+}', [Web\PersonController::class, 'renderPage']); - $routeCollector->addRoute('DELETE', '/users/{username:[a-zA-Z0-9]+}/movies/{id:\d+}/history', [Web\HistoryController::class, 'deleteHistoryEntry']); - $routeCollector->addRoute('POST', '/users/{username:[a-zA-Z0-9]+}/movies/{id:\d+}/history', [Web\HistoryController::class, 'createHistoryEntry']); - $routeCollector->addRoute('POST', '/users/{username:[a-zA-Z0-9]+}/movies/{id:\d+}/rating', [Web\Movie\MovieRatingController::class, 'updateRating']); - $routeCollector->addRoute('POST', '/log-movie', [Web\HistoryController::class, 'logMovie']); - $routeCollector->addRoute('POST', '/add-movie-to-watchlist', [Web\WatchlistController::class, 'addMovieToWatchlist']); - $routeCollector->addRoute('GET', '/fetchMovieRatingByTmdbdId', [Web\Movie\MovieRatingController::class, 'fetchMovieRatingByTmdbdId']); + $routes->add('GET', '/users/{username:[a-zA-Z0-9]+}/dashboard', [Web\DashboardController::class, 'render']); + $routes->add('GET', '/users/{username:[a-zA-Z0-9]+}/history', [Web\HistoryController::class, 'renderHistory']); + $routes->add('GET', '/users/{username:[a-zA-Z0-9]+}/watchlist', [Web\WatchlistController::class, 'renderWatchlist']); + $routes->add('GET', '/users/{username:[a-zA-Z0-9]+}/movies', [Web\MoviesController::class, 'renderPage']); + $routes->add('GET', '/users/{username:[a-zA-Z0-9]+}/actors', [Web\ActorsController::class, 'renderPage']); + $routes->add('GET', '/users/{username:[a-zA-Z0-9]+}/directors', [Web\DirectorsController::class, 'renderPage']); + $routes->add('GET', '/users/{username:[a-zA-Z0-9]+}/movies/{id:\d+}', [Web\Movie\MovieController::class, 'renderPage']); + $routes->add('GET', '/users/{username:[a-zA-Z0-9]+}/persons/{id:\d+}', [Web\PersonController::class, 'renderPage']); + $routes->add('DELETE', '/users/{username:[a-zA-Z0-9]+}/movies/{id:\d+}/history', [Web\HistoryController::class, 'deleteHistoryEntry'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/users/{username:[a-zA-Z0-9]+}/movies/{id:\d+}/history', [Web\HistoryController::class, 'createHistoryEntry'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/users/{username:[a-zA-Z0-9]+}/movies/{id:\d+}/rating', [ + Web\Movie\MovieRatingController::class, + 'updateRating' + ], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/log-movie', [Web\HistoryController::class, 'logMovie'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('POST', '/add-movie-to-watchlist', [Web\WatchlistController::class, 'addMovieToWatchlist'], [Web\Middleware\UserIsAuthenticated::class]); + $routes->add('GET', '/fetchMovieRatingByTmdbdId', [Web\Movie\MovieRatingController::class, 'fetchMovieRatingByTmdbdId'], [Web\Middleware\UserIsAuthenticated::class]); - // Added last, so that more specific routes can be defined (possible username vs route collisions here!) - $routeCollector->addRoute('GET', '/{username:[a-zA-Z0-9]+}[/]', [Web\DashboardController::class, 'redirectToDashboard']); + $routerService->addRoutesToRouteCollector($routeCollector, $routes); } -function addApiRoutes(FastRoute\RouteCollector $routeCollector) : void +function addApiRoutes(RouterService $routerService, FastRoute\RouteCollector $routeCollector) : void { - $routeCollector->addRoute('GET', '/openapi.json', [Api\OpenApiController::class, 'getSchema']); - $routeCollector->addRoute('GET', '/users/{username:[a-zA-Z0-9]+}/history', [Api\HistoryController::class, 'getHistory']); - $routeCollector->addRoute('GET', '/users/{username:[a-zA-Z0-9]+}/watchlist', [Api\WatchlistController::class, 'getWatchlist']); + $routes = RouteList::create(); + + $routes->add('GET', '/openapi.json', [Api\OpenApiController::class, 'getSchema']); + $routes->add('GET', '/users/{username:[a-zA-Z0-9]+}/history', [Api\HistoryController::class, 'getHistory']); + $routes->add('GET', '/users/{username:[a-zA-Z0-9]+}/watchlist', [Api\WatchlistController::class, 'getWatchlist']); + + $routerService->addRoutesToRouteCollector($routeCollector, $routes); } diff --git a/src/Factory.php b/src/Factory.php index d390f189..c3d3c48c 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -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; @@ -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), ); } @@ -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]); @@ -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() @@ -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'), @@ -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( @@ -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 diff --git a/src/HttpController/Web/AuthenticationController.php b/src/HttpController/Web/AuthenticationController.php index a933496f..edaf6084 100644 --- a/src/HttpController/Web/AuthenticationController.php +++ b/src/HttpController/Web/AuthenticationController.php @@ -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'); diff --git a/src/HttpController/Web/CreateUserController.php b/src/HttpController/Web/CreateUserController.php index dc7a4bd9..307afe59 100644 --- a/src/HttpController/Web/CreateUserController.php +++ b/src/HttpController/Web/CreateUserController.php @@ -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']; @@ -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'); diff --git a/src/HttpController/Web/DashboardController.php b/src/HttpController/Web/DashboardController.php index 746d0358..b984c05d 100644 --- a/src/HttpController/Web/DashboardController.php +++ b/src/HttpController/Web/DashboardController.php @@ -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']); diff --git a/src/HttpController/Web/EmbyController.php b/src/HttpController/Web/EmbyController.php index 96d41ed5..7abd4547 100644 --- a/src/HttpController/Web/EmbyController.php +++ b/src/HttpController/Web/EmbyController.php @@ -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(); @@ -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)])); diff --git a/src/HttpController/Web/ExportController.php b/src/HttpController/Web/ExportController.php index ee0eadba..7b5581e4 100644 --- a/src/HttpController/Web/ExportController.php +++ b/src/HttpController/Web/ExportController.php @@ -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; diff --git a/src/HttpController/Web/HistoryController.php b/src/HttpController/Web/HistoryController.php index 1aa68092..ec27ff11 100644 --- a/src/HttpController/Web/HistoryController.php +++ b/src/HttpController/Web/HistoryController.php @@ -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']) { @@ -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']) { @@ -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()); diff --git a/src/HttpController/Web/ImportController.php b/src/HttpController/Web/ImportController.php index 79c07b0a..ed59cb2d 100644 --- a/src/HttpController/Web/ImportController.php +++ b/src/HttpController/Web/ImportController.php @@ -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(); diff --git a/src/HttpController/Web/JellyfinController.php b/src/HttpController/Web/JellyfinController.php index 93508de0..dde92211 100644 --- a/src/HttpController/Web/JellyfinController.php +++ b/src/HttpController/Web/JellyfinController.php @@ -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']; @@ -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(); @@ -94,10 +86,6 @@ 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)])); @@ -105,10 +93,6 @@ public function regenerateJellyfinWebhookUrl() : Response public function removeJellyfinAuthentication() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $jellyfinAuthentication = $this->userApi->findJellyfinAuthentication($userId); @@ -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(); @@ -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(); @@ -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()); diff --git a/src/HttpController/Web/JobController.php b/src/HttpController/Web/JobController.php index f6079379..9b53d699 100644 --- a/src/HttpController/Web/JobController.php +++ b/src/HttpController/Web/JobController.php @@ -22,7 +22,6 @@ class JobController public function __construct( private readonly Authentication $authenticationService, private readonly JobQueueApi $jobQueueApi, - private readonly UserApi $userApi, private readonly LetterboxdCsvValidator $letterboxdImportHistoryFileValidator, private readonly SessionWrapper $sessionWrapper, private readonly string $appStorageDirectory, @@ -31,10 +30,6 @@ public function __construct( public function getJobs(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $parameters = $request->getGetParameters(); $jobType = JobType::createFromString($parameters['type']); @@ -46,10 +41,6 @@ public function getJobs(Request $request) : Response public function purgeAllJobs() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $this->jobQueueApi->purgeAllJobs(); return Response::createSeeOther('/settings/server/jobs'); @@ -57,10 +48,6 @@ public function purgeAllJobs() : Response public function purgeProcessedJobs() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $this->jobQueueApi->purgeProcessedJobs(); return Response::createSeeOther('/settings/server/jobs'); @@ -68,10 +55,6 @@ public function purgeProcessedJobs() : Response public function scheduleLetterboxdDiaryImport(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $fileParameters = $request->getFileParameters(); if (empty($fileParameters['diaryCsv']['tmp_name']) === true) { @@ -106,10 +89,6 @@ public function scheduleLetterboxdDiaryImport(Request $request) : Response public function scheduleLetterboxdRatingsImport(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $fileParameters = $request->getFileParameters(); if (empty($fileParameters['ratingsCsv']['tmp_name']) === true) { @@ -150,14 +129,7 @@ public function scheduleLetterboxdRatingsImport(Request $request) : Response public function schedulePlexWatchlistImport() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $currentUser = $this->authenticationService->getCurrentUser(); - if ($currentUser->getPlexAccessToken() === null) { - return Response::createBadRequest(PlexAuthenticationMissing::create()->getMessage()); - } $this->jobQueueApi->addPlexImportWatchlistJob($currentUser->getId()); @@ -170,17 +142,8 @@ public function schedulePlexWatchlistImport() : Response public function scheduleJellyfinImportHistory() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $currentUserId = $this->authenticationService->getCurrentUserId(); - $jellyfinAuthentication = $this->userApi->findJellyfinAuthentication($currentUserId); - if ($jellyfinAuthentication === null) { - return Response::createBadRequest(JellyfinInvalidAuthentication::create()->getMessage()); - } - $this->jobQueueApi->addJellyfinImportMoviesJob($currentUserId); return Response::create( @@ -192,17 +155,8 @@ public function scheduleJellyfinImportHistory() : Response public function scheduleJellyfinExportHistory() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $currentUserId = $this->authenticationService->getCurrentUserId(); - $jellyfinAuthentication = $this->userApi->findJellyfinAuthentication($currentUserId); - if ($jellyfinAuthentication === null) { - return Response::createBadRequest(JellyfinInvalidAuthentication::create()->getMessage()); - } - $this->jobQueueApi->addJellyfinExportMoviesJob($currentUserId); return Response::create( @@ -214,10 +168,6 @@ public function scheduleJellyfinExportHistory() : Response public function scheduleTraktHistorySync() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $this->jobQueueApi->addTraktImportHistoryJob($this->authenticationService->getCurrentUserId()); $this->sessionWrapper->set('scheduledTraktHistoryImport', true); @@ -231,10 +181,6 @@ public function scheduleTraktHistorySync() : Response public function scheduleTraktRatingsSync() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $this->jobQueueApi->addTraktImportRatingsJob($this->authenticationService->getCurrentUserId()); $this->sessionWrapper->set('scheduledTraktRatingsImport', true); diff --git a/src/HttpController/Web/LandingPageController.php b/src/HttpController/Web/LandingPageController.php index 9c8a56f8..63fb1842 100644 --- a/src/HttpController/Web/LandingPageController.php +++ b/src/HttpController/Web/LandingPageController.php @@ -13,8 +13,6 @@ class LandingPageController { public function __construct( private readonly Environment $twig, - private readonly Authentication $authenticationService, - private readonly UserApi $userApi, private readonly SessionWrapper $sessionWrapper, private readonly bool $registrationEnabled, private readonly ?string $defaultEmail, @@ -24,16 +22,6 @@ public function __construct( public function render() : Response { - if ($this->authenticationService->isUserAuthenticated() === true) { - $userName = $this->authenticationService->getCurrentUser()->getName(); - - return Response::createSeeOther("/users/$userName/dashboard"); - } - - if ($this->userApi->hasUsers() === false) { - return Response::createSeeOther('/create-user'); - } - $failedLogin = $this->sessionWrapper->has('failedLogin'); $deletedAccount = $this->sessionWrapper->has('deletedAccount'); $invalidTotpCode = $this->sessionWrapper->has('invalidTotpCode'); diff --git a/src/HttpController/Web/Middleware/MiddlewareInterface.php b/src/HttpController/Web/Middleware/MiddlewareInterface.php new file mode 100644 index 00000000..e9416d56 --- /dev/null +++ b/src/HttpController/Web/Middleware/MiddlewareInterface.php @@ -0,0 +1,11 @@ +userApi->hasUsers() === true) { + return null; + } + + return Response::createSeeOther('/create-user'); + } +} diff --git a/src/HttpController/Web/Middleware/ServerHasRegistrationEnabled.php b/src/HttpController/Web/Middleware/ServerHasRegistrationEnabled.php new file mode 100644 index 00000000..5c2f8cc5 --- /dev/null +++ b/src/HttpController/Web/Middleware/ServerHasRegistrationEnabled.php @@ -0,0 +1,22 @@ +registrationEnabled === false) { + return null; + } + + return Response::createForbidden(); + } +} diff --git a/src/HttpController/Web/Middleware/ServerHasUsers.php b/src/HttpController/Web/Middleware/ServerHasUsers.php new file mode 100644 index 00000000..8a977267 --- /dev/null +++ b/src/HttpController/Web/Middleware/ServerHasUsers.php @@ -0,0 +1,23 @@ +userApi->hasUsers() === false) { + return null; + } + + return Response::createSeeOther('/'); + } +} diff --git a/src/HttpController/Web/Middleware/UserHasJellyfinToken.php b/src/HttpController/Web/Middleware/UserHasJellyfinToken.php new file mode 100644 index 00000000..85895627 --- /dev/null +++ b/src/HttpController/Web/Middleware/UserHasJellyfinToken.php @@ -0,0 +1,28 @@ +userApi->findJellyfinAuthentication($this->authenticationService->getCurrentUserId()); + + if ($jellyfinAuthentication !== null) { + return null; + } + + return Response::createBadRequest(JellyfinInvalidAuthentication::create()->getMessage()); + } +} diff --git a/src/HttpController/Web/Middleware/UserIsAdmin.php b/src/HttpController/Web/Middleware/UserIsAdmin.php new file mode 100644 index 00000000..583cc6de --- /dev/null +++ b/src/HttpController/Web/Middleware/UserIsAdmin.php @@ -0,0 +1,23 @@ +authenticationService->getCurrentUser()->isAdmin() === true) { + return null; + } + + return Response::createForbidden(); + } +} diff --git a/src/HttpController/Web/Middleware/UserIsAuthenticated.php b/src/HttpController/Web/Middleware/UserIsAuthenticated.php new file mode 100644 index 00000000..ddc0af62 --- /dev/null +++ b/src/HttpController/Web/Middleware/UserIsAuthenticated.php @@ -0,0 +1,23 @@ +authenticationService->isUserAuthenticated() === true) { + return null; + } + + return Response::createForbidden(); + } +} diff --git a/src/HttpController/Web/Middleware/UserIsUnauthenticated.php b/src/HttpController/Web/Middleware/UserIsUnauthenticated.php new file mode 100644 index 00000000..e84d7e8f --- /dev/null +++ b/src/HttpController/Web/Middleware/UserIsUnauthenticated.php @@ -0,0 +1,25 @@ +authenticationService->isUserAuthenticated() === false) { + return null; + } + + $userName = $this->authenticationService->getCurrentUser()->getName(); + + return Response::createSeeOther("/users/$userName/dashboard"); + } +} diff --git a/src/HttpController/Web/Movie/MovieController.php b/src/HttpController/Web/Movie/MovieController.php index 349e47f6..9d528916 100644 --- a/src/HttpController/Web/Movie/MovieController.php +++ b/src/HttpController/Web/Movie/MovieController.php @@ -20,7 +20,6 @@ public function __construct( private readonly Environment $twig, private readonly MovieApi $movieApi, private readonly MovieWatchlistApi $movieWatchlistApi, - private readonly Authentication $authenticationService, private readonly UserPageAuthorizationChecker $userPageAuthorizationChecker, private readonly SyncMovie $tmdbMovieSync, private readonly ImdbMovieRatingSync $imdbMovieRatingSync, @@ -30,10 +29,6 @@ public function __construct( public function refreshImdbRating(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createForbidden(); - } - $movieId = (int)$request->getRouteParameters()['id']; $movie = $this->movieApi->findByIdFormatted($movieId); @@ -48,10 +43,6 @@ public function refreshImdbRating(Request $request) : Response public function refreshTmdbData(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createForbidden(); - } - $movieId = (int)$request->getRouteParameters()['id']; $movie = $this->movieApi->findByIdFormatted($movieId); diff --git a/src/HttpController/Web/Movie/MovieRatingController.php b/src/HttpController/Web/Movie/MovieRatingController.php index c9870e0e..8bd1a1ac 100644 --- a/src/HttpController/Web/Movie/MovieRatingController.php +++ b/src/HttpController/Web/Movie/MovieRatingController.php @@ -22,10 +22,6 @@ public function __construct( public function fetchMovieRatingByTmdbdId(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $tmdbId = $request->getGetParameters()['tmdbId'] ?? null; @@ -43,10 +39,6 @@ public function fetchMovieRatingByTmdbdId(Request $request) : Response public function updateRating(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createForbidden(); - } - $userId = $this->authenticationService->getCurrentUserId(); if ($this->userApi->fetchUser($userId)->getName() !== $request->getRouteParameters()['username']) { diff --git a/src/HttpController/Web/Movie/MovieWatchlistController.php b/src/HttpController/Web/Movie/MovieWatchlistController.php index 0e9e2dbd..f2522e04 100644 --- a/src/HttpController/Web/Movie/MovieWatchlistController.php +++ b/src/HttpController/Web/Movie/MovieWatchlistController.php @@ -17,10 +17,6 @@ public function __construct( public function addToWatchlist(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createForbidden(); - } - $movieId = (int)$request->getRouteParameters()['id']; $userId = $this->authenticationService->getCurrentUser()->getId(); @@ -31,10 +27,6 @@ public function addToWatchlist(Request $request) : Response public function removeFromWatchlist(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createForbidden(); - } - $movieId = (int)$request->getRouteParameters()['id']; $userId = $this->authenticationService->getCurrentUser()->getId(); diff --git a/src/HttpController/Web/NetflixController.php b/src/HttpController/Web/NetflixController.php index 81074f56..808159a6 100644 --- a/src/HttpController/Web/NetflixController.php +++ b/src/HttpController/Web/NetflixController.php @@ -25,10 +25,6 @@ public function __construct( public function importNetflixData(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $items = Json::decode($request->getBody()); @@ -43,10 +39,6 @@ public function importNetflixData(Request $request) : Response */ public function matchNetflixActivityCsvWithTmdbMovies(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $files = $request->getFileParameters(); $postParameters = $request->getPostParameters(); if (empty($files['netflixActivityCsv']) === true || empty($postParameters['netflixActivityCsvDateFormat']) === true) { @@ -74,10 +66,6 @@ public function matchNetflixActivityCsvWithTmdbMovies(Request $request) : Respon public function searchTmbd(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $input = Json::decode($request->getBody()); $tmdbSearchResult = $this->tmdbApi->searchMovie($input['query']); diff --git a/src/HttpController/Web/PlexController.php b/src/HttpController/Web/PlexController.php index e5591a4b..001db998 100644 --- a/src/HttpController/Web/PlexController.php +++ b/src/HttpController/Web/PlexController.php @@ -32,10 +32,6 @@ public function __construct( public function deletePlexWebhookUrl() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $this->userApi->deletePlexWebhookId($this->authenticationService->getCurrentUserId()); return Response::createOk(); @@ -43,10 +39,6 @@ public function deletePlexWebhookUrl() : Response public function generatePlexAuthenticationUrl() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createForbidden(); - } - $plexAccessToken = $this->userApi->findPlexAccessToken($this->authenticationService->getCurrentUserId()); if ($plexAccessToken !== null) { return Response::createBadRequest('User is already authenticated'); @@ -84,10 +76,6 @@ public function handlePlexWebhook(Request $request) : Response public function processPlexCallback() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createForbidden(); - } - $plexClientId = $this->userApi->findPlexClientId($this->authenticationService->getCurrentUserId()); $plexClientCode = $this->userApi->findTemporaryPlexCode($this->authenticationService->getCurrentUserId()); if ($plexClientId === null || $plexClientCode === null) { @@ -112,10 +100,6 @@ public function processPlexCallback() : Response public function regeneratePlexWebhookUrl() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $webhookId = $this->userApi->regeneratePlexWebhookId($this->authenticationService->getCurrentUserId()); return Response::createJson(Json::encode(['url' => $this->webhookUrlBuilder->buildPlexWebhookUrl($webhookId)])); @@ -123,10 +107,6 @@ public function regeneratePlexWebhookUrl() : Response public function removePlexAccessTokens() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $this->userApi->updatePlexAccessToken($userId, null); @@ -139,10 +119,6 @@ public function removePlexAccessTokens() : Response public function savePlexServerUrl(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $plexServerUrl = Json::decode($request->getBody())['plexServerUrl']; @@ -165,10 +141,6 @@ public function savePlexServerUrl(Request $request) : Response public function verifyPlexServerUrl(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $plexAccessToken = $this->authenticationService->getCurrentUser()->getPlexAccessToken(); if ($plexAccessToken === null) { return Response::createBadRequest('Plex authentication is missing'); diff --git a/src/HttpController/Web/SettingsController.php b/src/HttpController/Web/SettingsController.php index 20925a96..5dd2afbc 100644 --- a/src/HttpController/Web/SettingsController.php +++ b/src/HttpController/Web/SettingsController.php @@ -57,10 +57,6 @@ public function __construct( public function deleteAccount() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $user = $this->userApi->fetchUser($userId); @@ -83,10 +79,6 @@ public function deleteAccount() : Response public function deleteApiToken() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $this->userApi->deleteApiToken($this->authenticationService->getCurrentUserId()); return Response::createOk(); @@ -94,10 +86,6 @@ public function deleteApiToken() : Response public function deleteHistory() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $this->movieApi->deleteHistoryByUserId($this->authenticationService->getCurrentUserId()); $this->sessionWrapper->set('deletedUserHistory', true); @@ -111,10 +99,6 @@ public function deleteHistory() : Response public function deleteRatings() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $this->movieApi->deleteRatingsByUserId($this->authenticationService->getCurrentUserId()); $this->sessionWrapper->set('deletedUserRatings', true); @@ -128,10 +112,6 @@ public function deleteRatings() : Response public function generateLetterboxdExportData() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $options = new ZipStream\Option\Archive(); @@ -152,10 +132,6 @@ public function generateLetterboxdExportData() : Response public function getApiToken() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); return Response::createJson(Json::encode(['token' => $this->userApi->findApiTokenByUserId($userId)])); @@ -163,10 +139,6 @@ public function getApiToken() : Response public function regenerateApiToken() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $this->userApi->deleteApiToken($userId); @@ -177,10 +149,6 @@ public function regenerateApiToken() : Response public function renderAppPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - return Response::create( StatusCode::createOk(), $this->twig->render('page/settings-app.html.twig', [ @@ -193,10 +161,6 @@ public function renderAppPage() : Response public function renderDashboardAccountPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $user = $this->authenticationService->getCurrentUser(); $dashboardRows = $this->dashboardFactory->createDashboardRowsForUser($user); @@ -215,10 +179,6 @@ public function renderDashboardAccountPage() : Response public function renderDataAccountPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $importHistorySuccessful = $this->sessionWrapper->find('importHistorySuccessful'); @@ -255,10 +215,6 @@ public function renderDataAccountPage() : Response public function renderEmbyPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $user = $this->userApi->fetchUser($this->authenticationService->getCurrentUserId()); $applicationUrl = $this->serverSettings->getApplicationUrl(); @@ -280,10 +236,6 @@ public function renderEmbyPage() : Response public function renderGeneralAccountPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $user = $this->authenticationService->getCurrentUser(); return Response::create( @@ -304,10 +256,6 @@ public function renderGeneralAccountPage() : Response public function renderJellyfinPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $user = $this->userApi->fetchUser($this->authenticationService->getCurrentUserId()); $applicationUrl = $this->serverSettings->getApplicationUrl(); @@ -343,10 +291,6 @@ public function renderJellyfinPage() : Response public function renderLetterboxdPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $user = $this->userApi->fetchUser($this->authenticationService->getCurrentUserId()); $letterboxdDiarySyncSuccessful = $this->sessionWrapper->find('letterboxdDiarySyncSuccessful'); @@ -375,10 +319,6 @@ public function renderLetterboxdPage() : Response public function renderNetflixPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - return Response::create( StatusCode::createOk(), $this->twig->render('page/settings-integration-netflix.html.twig'), @@ -387,10 +327,6 @@ public function renderNetflixPage() : Response public function renderPlexPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $plexAccessToken = null; $plexIdentifier = $this->serverSettings->getPlexIdentifier(); @@ -433,10 +369,6 @@ public function renderPlexPage() : Response public function renderSecurityAccountPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $user = $this->authenticationService->getCurrentUser(); $totpEnabled = $this->twoFactorAuthenticationService->findTotpUri($user->getId()) === null ? false : true; @@ -462,14 +394,6 @@ public function renderSecurityAccountPage() : Response public function renderServerEmailPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - - if ($this->authenticationService->getCurrentUser()->isAdmin() === false) { - return Response::createSeeOther('/'); - } - return Response::create( StatusCode::createOk(), $this->twig->render('page/settings-server-email.html.twig', [ @@ -493,14 +417,6 @@ public function renderServerEmailPage() : Response public function renderServerGeneralPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - - if ($this->authenticationService->getCurrentUser()->isAdmin() === false) { - return Response::createSeeOther('/'); - } - return Response::create( StatusCode::createOk(), $this->twig->render('page/settings-server-general.html.twig', [ @@ -514,14 +430,6 @@ public function renderServerGeneralPage() : Response public function renderServerJobsPage(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - - if ($this->authenticationService->getCurrentUser()->isAdmin() === false) { - return Response::createSeeOther('/'); - } - $jobsPerPage = $request->getGetParameters()['jpp'] ?? 30; $jobs = $this->jobQueueApi->fetchJobsForStatusPage((int)$jobsPerPage); @@ -537,14 +445,6 @@ public function renderServerJobsPage(Request $request) : Response public function renderServerUsersPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - - if ($this->authenticationService->getCurrentUser()->isAdmin() === false) { - return Response::createSeeOther('/'); - } - return Response::create( StatusCode::createOk(), $this->twig->render('page/settings-server-users.html.twig'), @@ -553,10 +453,6 @@ public function renderServerUsersPage() : Response public function renderTraktPage() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $traktCredentialsUpdated = $this->sessionWrapper->find('traktCredentialsUpdated'); $scheduledTraktHistoryImport = $this->sessionWrapper->find('scheduledTraktHistoryImport'); $scheduledTraktRatingsImport = $this->sessionWrapper->find('scheduledTraktRatingsImport'); @@ -580,10 +476,6 @@ public function renderTraktPage() : Response public function resetDashboardRows() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $this->userApi->updateVisibleDashboardRows($userId, null); @@ -597,14 +489,6 @@ public function resetDashboardRows() : Response public function sendTestEmail(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - - if ($this->authenticationService->getCurrentUser()->isAdmin() === false) { - return Response::createSeeOther('/'); - } - $requestData = Json::decode($request->getBody()); $smtpConfig = SmtpConfig::create( @@ -633,10 +517,6 @@ public function sendTestEmail(Request $request) : Response public function traktVerifyCredentials(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $requestData = Json::decode($request->getBody()); $clientId = $requestData['clientId'] ?? ''; @@ -651,10 +531,6 @@ public function traktVerifyCredentials(Request $request) : Response public function updateDashboardRows(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $bodyData = Json::decode($request->getBody()); @@ -675,10 +551,6 @@ public function updateDashboardRows(Request $request) : Response public function updateEmby(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $postParameters = Json::decode($request->getBody()); @@ -692,10 +564,6 @@ public function updateEmby(Request $request) : Response public function updateGeneral(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $requestData = Json::decode($request->getBody()); $privacyLevel = isset($requestData['privacyLevel']) === false ? 1 : (int)$requestData['privacyLevel']; @@ -721,10 +589,6 @@ public function updateGeneral(Request $request) : Response public function updateJellyfin(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $postParameters = Json::decode($request->getBody()); @@ -738,10 +602,6 @@ public function updateJellyfin(Request $request) : Response public function updatePassword(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $user = $this->userApi->fetchUser($userId); @@ -769,10 +629,6 @@ public function updatePassword(Request $request) : Response public function updatePlex(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $postParameters = Json::decode($request->getBody()); @@ -787,14 +643,6 @@ public function updatePlex(Request $request) : Response // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh public function updateServerEmail(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - - if ($this->authenticationService->getCurrentUser()->isAdmin() === false) { - return Response::createForbidden(); - } - $requestData = Json::decode($request->getBody()); $smtpHost = isset($requestData['smtpHost']) === false ? null : $requestData['smtpHost']; @@ -832,14 +680,6 @@ public function updateServerEmail(Request $request) : Response public function updateServerGeneral(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - - if ($this->authenticationService->getCurrentUser()->isAdmin() === false) { - return Response::createForbidden(); - } - $requestData = Json::decode($request->getBody()); $tmdbApiKey = isset($requestData['tmdbApiKey']) === false ? null : $requestData['tmdbApiKey']; @@ -857,10 +697,6 @@ public function updateServerGeneral(Request $request) : Response public function updateTrakt(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $postParameters = $request->getPostParameters(); diff --git a/src/HttpController/Web/TwoFactorAuthenticationController.php b/src/HttpController/Web/TwoFactorAuthenticationController.php index ec4d790d..0fa6a0ad 100644 --- a/src/HttpController/Web/TwoFactorAuthenticationController.php +++ b/src/HttpController/Web/TwoFactorAuthenticationController.php @@ -24,10 +24,6 @@ public function __construct( public function createTotpUri() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $currentUserName = $this->authenticationService->getCurrentUser()->getName(); $totp = $this->twoFactorAuthenticationFactory->createTotp($currentUserName); @@ -41,10 +37,6 @@ public function createTotpUri() : Response public function disableTOTP() : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $this->twoFactorAuthenticationApi->deleteTotp($this->authenticationService->getCurrentUserId()); $this->sessionWrapper->set('twoFactorAuthenticationDisabled', true); @@ -53,10 +45,6 @@ public function disableTOTP() : Response public function enableTOTP(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $requestData = Json::decode($request->getBody()); @@ -76,14 +64,6 @@ public function enableTOTP(Request $request) : Response public function verifyTotp(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === true) { - return Response::create( - StatusCode::createSeeOther(), - null, - [Header::createLocation($_SERVER['HTTP_REFERER'])], - ); - } - $userTotpInput = $request->getPostParameters()['totpCode']; $rememberMe = $this->sessionWrapper->find('rememberMe') ?? false; $userId = (int)$this->sessionWrapper->find('totpUserId'); diff --git a/src/HttpController/Web/UserController.php b/src/HttpController/Web/UserController.php index 9c677cc0..79c15f5c 100644 --- a/src/HttpController/Web/UserController.php +++ b/src/HttpController/Web/UserController.php @@ -51,10 +51,6 @@ public function createUser(Request $request) : Response public function deleteUser(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = (int)$request->getRouteParameters()['userId']; $currentUser = $this->authenticationService->getCurrentUser(); @@ -79,10 +75,6 @@ public function fetchUsers() : Response public function updateUser(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createForbidden(); - } - $userId = (int)$request->getRouteParameters()['userId']; $currentUser = $this->authenticationService->getCurrentUser(); diff --git a/src/HttpController/Web/WatchlistController.php b/src/HttpController/Web/WatchlistController.php index 10346681..df62d92d 100644 --- a/src/HttpController/Web/WatchlistController.php +++ b/src/HttpController/Web/WatchlistController.php @@ -32,10 +32,6 @@ public function __construct( public function addMovieToWatchlist(Request $request) : Response { - if ($this->authenticationService->isUserAuthenticated() === false) { - return Response::createSeeOther('/'); - } - $userId = $this->authenticationService->getCurrentUserId(); $requestData = Json::decode($request->getBody()); diff --git a/src/Service/Router/Dto/Route.php b/src/Service/Router/Dto/Route.php new file mode 100644 index 00000000..fc49af91 --- /dev/null +++ b/src/Service/Router/Dto/Route.php @@ -0,0 +1,39 @@ +handler; + } + + public function getMethod() : string + { + return $this->httpMethod; + } + + public function getRoute() : string + { + return $this->route; + } + + public function getMiddleware() : ?array + { + return $this->middleware; + } +} diff --git a/src/Service/Router/Dto/RouteList.php b/src/Service/Router/Dto/RouteList.php new file mode 100644 index 00000000..7d853d91 --- /dev/null +++ b/src/Service/Router/Dto/RouteList.php @@ -0,0 +1,25 @@ +data[] = $route; + + return $route; + } +} diff --git a/src/Service/Router/RouterService.php b/src/Service/Router/RouterService.php new file mode 100644 index 00000000..95a1e8ea --- /dev/null +++ b/src/Service/Router/RouterService.php @@ -0,0 +1,23 @@ +addRoute( + $route->getMethod(), + $route->getRoute(), + [ + 'handler' => $route->getHandler(), + 'middleware' => $route->getMiddleware() + ], + ); + } + } +} diff --git a/src/ValueObject/Http/Request.php b/src/ValueObject/Http/Request.php index 5112969c..b39ea9a8 100644 --- a/src/ValueObject/Http/Request.php +++ b/src/ValueObject/Http/Request.php @@ -7,7 +7,7 @@ class Request { private array $routeParameters = []; - + private function __construct( private readonly string $path, private readonly array $getParameters,