From 7ed5bcd29aa47aae378af43286c608e460f9e5f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Tue, 8 Sep 2026 12:16:29 +0200 Subject: [PATCH] feat: maintenance mode --- .env | 5 ++ config/services.yaml | 9 ++ src/EventListener/MaintenanceModeListener.php | 86 +++++++++++++++++++ templates/maintenance/index.html.twig | 22 +++++ 4 files changed, 122 insertions(+) create mode 100644 src/EventListener/MaintenanceModeListener.php create mode 100644 templates/maintenance/index.html.twig diff --git a/.env b/.env index e8649de..1b4b7b6 100644 --- a/.env +++ b/.env @@ -104,3 +104,8 @@ FEATURE_DATEV_EMAIL=false FEATURE_MYEP_LOGIN=false UPLOAD_REPLACEMENT_FILE=assets/pdf/chicken.pdf + +MAINTENANCE_MODE_ENABLED=false +MAINTENANCE_MODE_IP_WHITELIST=188.245.62.21 +MAINTENANCE_MODE_ROUTE_WHITELIST= +MAINTENANCE_MODE_PATH_WHITELIST= diff --git a/config/services.yaml b/config/services.yaml index d09d0cf..99cce9e 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -1,3 +1,4 @@ +# yaml-language-server: $schema=../vendor/symfony/dependency-injection/Loader/schema/services.schema.json parameters: bpn_crm_id_admin: '%env(int:APP_BPN_CRM_ID_ADMIN)%' bpn_crm_id_manager: '%env(int:APP_BPN_CRM_ID_MANAGER)%' @@ -245,6 +246,14 @@ services: $binGs: '%env(BIN_GS)%' $binConvert: '%env(BIN_CONVERT)%' + App\EventListener\MaintenanceModeListener: + arguments: + $options: + enabled: '%env(bool:MAINTENANCE_MODE_ENABLED)%' + whitelisted_ips: '%env(csv:MAINTENANCE_MODE_IP_WHITELIST)%' + whitelisted_routes: '%env(csv:MAINTENANCE_MODE_ROUTE_WHITELIST)%' + whitelisted_paths: '%env(csv:MAINTENANCE_MODE_PATH_WHITELIST)%' + App\EventListener\UploadSessionListener: tags: - name: kernel.event_listener diff --git a/src/EventListener/MaintenanceModeListener.php b/src/EventListener/MaintenanceModeListener.php new file mode 100644 index 0000000..5be3ebd --- /dev/null +++ b/src/EventListener/MaintenanceModeListener.php @@ -0,0 +1,86 @@ + + */ + private array $config; + + /** + * @param array $options + */ + public function __construct(private readonly Environment $twig, array $options) + { + $this->config = $this->resolveConfig($options); + } + + public function onKernelRequest(RequestEvent $event): void + { + if (false === $event->isMainRequest()) { + return; + } + + if (false === $this->config['enabled']) { + return; + } + + $request = $event->getRequest(); + + // Check requested path against whitelist + foreach ($this->config['whitelisted_paths'] as $whitelistedPath) { + $prefix = rtrim((string) $whitelistedPath, '/'); + + if ($request->getPathInfo() === $prefix || str_starts_with($request->getPathInfo(), $prefix.'/')) { + return; + } + } + + // Check user's IP against whitelist + if (true === IpUtils::checkIp($request->getClientIp(), $this->config['whitelisted_ips'])) { + $request->attributes->set('_maintenance_mode_allowed', true); + + return; + } + + // Check requested route against whitelist + if (true === in_array($request->attributes->get('_route'), $this->config['whitelisted_routes'])) { + return; + } + + $content = $this->twig->render('maintenance/index.html.twig'); + + $event->setResponse(new Response($content, Response::HTTP_SERVICE_UNAVAILABLE)); + } + + /** + * @param array $options + * + * @return array + */ + private function resolveConfig(array $options): array + { + $optionsResolver = new OptionsResolver(); + $optionsResolver + ->setDefaults([ + 'enabled' => false, + 'whitelisted_ips' => [], + 'whitelisted_routes' => [], + 'whitelisted_paths' => [], + ]) + ; + + return $optionsResolver->resolve($options); + } +} diff --git a/templates/maintenance/index.html.twig b/templates/maintenance/index.html.twig new file mode 100644 index 0000000..d170c28 --- /dev/null +++ b/templates/maintenance/index.html.twig @@ -0,0 +1,22 @@ +{% extends 'base.html.twig' %} + +{% block body %} +
+
+

+ My E&P Team + MyE&P Team +

+

+ ...ist außer Betrieb +

+

+ Wir müssen gerade leider unaufschiebbare Wartungsarbeiten durchführen, sind aber schnellstmöglich wieder + online. Versprochen. +

+

+ Vielen Dank für Dein Verständnis! +

+
+
+{% endblock %}