diff --git a/.env b/.env index a691ab6..e064be6 100644 --- a/.env +++ b/.env @@ -98,3 +98,4 @@ STRIPE_SECRET_KEY=sk_test_*** ###< stripe/stripe-php ### INTRANET_LOCK=true TVA_ENABLED=false +MAINTENANCE_ENABLED=false diff --git a/.gitea/workflows/install-deps.yml b/.gitea/workflows/install-deps.yml index 2f91076..2ad4c0a 100644 --- a/.gitea/workflows/install-deps.yml +++ b/.gitea/workflows/install-deps.yml @@ -1,34 +1,25 @@ -# Nom du workflow -name: Symfony CI - Install, Test, Build, Attest & Deploy +deploy: + name: đ Deploy to Production + runs-on: ubuntu-latest # N'oublie pas de prĂ©ciser l'OS du runner + steps: + - name: Deploy with SSH + uses: appleboy/ssh-action@v1.0.0 + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USER }} + key: ${{ secrets.SSH_PRIVATE_KEY }} + port: 22 + script: | + cd /var/www/ludikevent-intranet -# DĂ©clencheurs du workflow -on: - push: - branches: - - master # Ou 'main' - pull_request: - types: [opened, synchronize, reopened] - branches: - - master # Ou 'main' + # 1. Activer la maintenance + php bin/console app:maintenance on -# Permissions nĂ©cessaires pour les actions utilisĂ©es -permissions: - contents: read - pull-requests: write - id-token: write - attestations: write - security-events: write # Requis pour Snyk pour poster les rĂ©sultats + # 2. Mise Ă jour du code + git pull -jobs: - deploy: - name: đ Deploy to Production - steps: - - name: Deploy with SSH & Ansible - uses: appleboy/ssh-action@v1.0.0 - with: - host: ${{ secrets.SSH_HOST }} - username: ${{ secrets.SSH_USER }} - key: ${{ secrets.SSH_PRIVATE_KEY }} - port: 22 - script: | - cd /var/www/ludikevent-intranet && git pull && nohup sh ./update.sh + # 3. ExĂ©cuter ton script d'update (migrations, install, etc.) + sh ./update.sh + + # 4. DĂ©sactiver la maintenance + php bin/console app:maintenance off diff --git a/config/services.yaml b/config/services.yaml index 1dd7780..ba660ea 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -24,3 +24,8 @@ services: # Utilisation du listener de Nelmio (identifiant officiel) $cspListener: '@nelmio_security.csp_listener' + App\Security\MaintenanceListener: + arguments: + $isMaintenance: '%env(MAINTENANCE_ENABLED)%' + tags: + - { name: kernel.event_listener, event: kernel.request, priority: 255 } diff --git a/src/Command/MaintenanceCommand.php b/src/Command/MaintenanceCommand.php new file mode 100644 index 0000000..dfdd78c --- /dev/null +++ b/src/Command/MaintenanceCommand.php @@ -0,0 +1,59 @@ +addArgument('status', InputArgument::REQUIRED, 'on ou off'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $status = $input->getArgument('status'); + $envFile = dirname(__DIR__, 2) . '/.env.local'; + + // Si .env.local n'existe pas, on prend le .env + if (!file_exists($envFile)) { + $envFile = dirname(__DIR__, 2) . '/.env'; + } + + $content = file_get_contents($envFile); + $value = ($status === 'on') ? 'true' : 'false'; + + // On remplace la valeur de la variable + if (preg_match('/MAINTENANCE_ENABLED=/', $content)) { + $content = preg_replace('/MAINTENANCE_ENABLED=(true|false)/', "MAINTENANCE_ENABLED=$value", $content); + } else { + $content .= "\nMAINTENANCE_ENABLED=$value"; + } + + file_put_contents($envFile, $content); + + // Vider le cache pour appliquer le changement + $io->note("Mise Ă jour du fichier .env et nettoyage du cache..."); + passthru('php bin/console cache:clear'); + + if ($status === 'on') { + $io->success('Mode maintenance ACTIVĂ âïž (Le site est cachĂ© au public)'); + } else { + $io->success('Mode maintenance DĂSACTIVĂ â (Le site est en ligne)'); + } + + return Command::SUCCESS; + } +} diff --git a/src/Security/IntranetLocked.php b/src/Security/IntranetLocked.php index 47476f6..ec7b8b4 100644 --- a/src/Security/IntranetLocked.php +++ b/src/Security/IntranetLocked.php @@ -43,6 +43,8 @@ class IntranetLocked public function onControl(RequestEvent $requestEvent): void { + + // On ignore Ă©galement le contrĂŽle des services pour l'IP whitelisted if ($this->isWhitelisted($requestEvent) || $this->isDebugRoute($requestEvent)) { return; diff --git a/src/Security/MaintenanceListener.php b/src/Security/MaintenanceListener.php new file mode 100644 index 0000000..be5edc9 --- /dev/null +++ b/src/Security/MaintenanceListener.php @@ -0,0 +1,40 @@ +twig = $twig; + $this->isMaintenance = filter_var($isMaintenance, FILTER_VALIDATE_BOOLEAN); + } + + public function onKernelRequest(RequestEvent $event) + { + // On n'active la maintenance que sur la requĂȘte principale (pas les sous-requĂȘtes) + if (!$event->isMainRequest()) { + return; + } + + // Si la maintenance est dĂ©sactivĂ©e, on ne fait rien + if (!$this->isMaintenance) { + return; + } + + // Si l'IP du visiteur est dans la whitelist, on le laisse passer + // On affiche la page de maintenance + $content = $this->twig->render('security/maintenance.twig'); + + // On renvoie une rĂ©ponse 503 (Service Unavailable) + $event->setResponse(new Response($content, 503)); + } +} diff --git a/templates/security/maintenance.twig b/templates/security/maintenance.twig new file mode 100644 index 0000000..7046946 --- /dev/null +++ b/templates/security/maintenance.twig @@ -0,0 +1,65 @@ + + +
+ + ++ On installe de nouvelles fonctionnalités pour rendre vos réservations encore plus ludiques. + On revient dans quelques minutes. +
+ + {# DĂ©coration de fond (forme abstraite) #} + ++ Ludik Event © {{ "now"|date("Y") }} - Hauts-de-France +
+ +