Skip to content

Commit

Permalink
管理者はメンテナンスモードを回避可能に変更
Browse files Browse the repository at this point in the history
  • Loading branch information
izayoi256 committed Mar 16, 2021
1 parent 9114846 commit 1e947c0
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 21 deletions.
20 changes: 13 additions & 7 deletions index.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use Eccube\Kernel;
use Eccube\Service\SystemService;
use Symfony\Component\Debug\Debug;
use Dotenv\Dotenv;
use Symfony\Component\HttpFoundation\Request;
Expand Down Expand Up @@ -62,13 +63,18 @@
$adminPath = env('ECCUBE_ADMIN_ROUTE', 'admin');
$adminPath = '/'.\trim($adminPath, '/').'/';
if (\strpos($pathInfo, $adminPath) !== 0) {
$locale = env('ECCUBE_LOCALE');
$templateCode = env('ECCUBE_TEMPLATE_CODE');
$baseUrl = \htmlspecialchars(\rawurldecode($request->getBaseUrl()), ENT_QUOTES);

header('HTTP/1.1 503 Service Temporarily Unavailable');
require __DIR__.'/maintenance.php';
return;
$maintenanceContents = file_get_contents($maintenanceFile);
$maintenanceToken = explode(':', $maintenanceContents)[1] ?? null;
$tokenInCookie = $request->cookies->get(SystemService::MAINTENANCE_TOKEN_KEY);
if ($tokenInCookie === null || $tokenInCookie !== $maintenanceToken) {
$locale = env('ECCUBE_LOCALE');
$templateCode = env('ECCUBE_TEMPLATE_CODE');
$baseUrl = \htmlspecialchars(\rawurldecode($request->getBaseUrl()), ENT_QUOTES);

header('HTTP/1.1 503 Service Temporarily Unavailable');
require __DIR__.'/maintenance.php';
return;
}
}
}

Expand Down
6 changes: 2 additions & 4 deletions src/Eccube/Controller/Admin/Content/MaintenanceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,16 @@ public function index(Request $request)

if ($form->isSubmitted() && $form->isValid()) {
$changeTo = $request->request->get('maintenance');
$path = $this->container->getParameter('eccube_content_maintenance_file_path');

if ($isMaintenance === false && $changeTo == 'on') {
// 現在メンテナンスモードではない かつ メンテナンスモードを有効 にした場合
// メンテナンスモードを有効にする
file_put_contents($path, null);

$this->systemService->enableMaintenance('', true);
$this->addSuccess('admin.content.maintenance_switch__on_message', 'admin');
} elseif ($isMaintenance && $changeTo == 'off') {
// 現在メンテナンスモード かつ メンテナンスモードを無効 にした場合
// メンテナンスモードを無効にする
unlink($path);
$this->systemService->disableMaintenanceNow('', true);

$this->addSuccess('admin.content.maintenance_switch__off_message', 'admin');
}
Expand Down
64 changes: 64 additions & 0 deletions src/Eccube/EventListener/MaintenanceListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

/*
* This file is part of EC-CUBE
*
* Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
*
* http://www.ec-cube.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Eccube\EventListener;

use Eccube\Entity;
use Eccube\Request\Context;
use Eccube\Service\SystemService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class MaintenanceListener implements EventSubscriberInterface
{

/** @var Context */
protected $requestContext;

/** @var SystemService */
protected $systemService;

public function __construct(Context $requestContext, SystemService $systemService)
{
$this->requestContext = $requestContext;
$this->systemService = $systemService;
}

public static function getSubscribedEvents()
{
return [
KernelEvents::RESPONSE => ['onResponse'],
];
}

public function onResponse(FilterResponseEvent $event)
{
$response = $event->getResponse();

if (!$this->systemService->isMaintenanceMode()) {
$response->headers->clearCookie(SystemService::MAINTENANCE_TOKEN_KEY);
return;
}

$user = $this->requestContext->getCurrentUser();
if ($user instanceof Entity\Member && $this->requestContext->isAdmin()) {
$cookie = new Cookie(
SystemService::MAINTENANCE_TOKEN_KEY,
$this->systemService->getMaintenanceToken()
);
$response->headers->setCookie($cookie);
}
}
}
57 changes: 47 additions & 10 deletions src/Eccube/Service/SystemService.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,21 @@
namespace Eccube\Service;

use Doctrine\ORM\EntityManagerInterface;
use Eccube\Util\StringUtil;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\DataCollector\MemoryDataCollector;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use function explode;
use function file_exists;
use function file_get_contents;
use function file_put_contents;
use function unlink;

class SystemService implements EventSubscriberInterface
{
const MAINTENANCE_TOKEN_KEY = 'maintenance_token';
const AUTO_MAINTENANCE = 'auto_maintenance';
const AUTO_MAINTENANCE_UPDATE = 'auto_maintenance_update';

Expand Down Expand Up @@ -140,20 +147,26 @@ public function getMemoryLimit()
*
* @param bool $isEnable
* @param string $mode
* @param bool $force
*/
public function switchMaintenance($isEnable = false, $mode = self::AUTO_MAINTENANCE)
public function switchMaintenance($isEnable = false, $mode = self::AUTO_MAINTENANCE, bool $force = false): void
{
$isMaintenanceMode = $this->isMaintenanceMode();
$path = $this->container->getParameter('eccube_content_maintenance_file_path');
if ($isEnable) {
$this->enableMaintenance($mode, $force);
} else {
$this->disableMaintenanceNow($mode, $force);
}
}

if ($isEnable && $isMaintenanceMode === false) {
file_put_contents($path, $mode);
} elseif ($isEnable === false && $isMaintenanceMode) {
$contents = file_get_contents($path);
if ($contents == $mode) {
unlink($path);
}
public function getMaintenanceToken(): ?string
{
$path = $this->container->getParameter('eccube_content_maintenance_file_path');
if (!file_exists($path)) {
return null;
}

$contents = file_get_contents($path);
return explode(':', $contents)[1] ?? null;
}

/**
Expand All @@ -168,6 +181,15 @@ public function disableMaintenanceEvent(PostResponseEvent $event)
}
}

public function enableMaintenance($mode = self::AUTO_MAINTENANCE, bool $force = false): void
{
if ($force || !$this->isMaintenanceMode()) {
$path = $this->container->getParameter('eccube_content_maintenance_file_path');
$token = StringUtil::random(32);
file_put_contents($path, "{$mode}:{$token}");
}
}

/**
* メンテナンスモードを解除する
*
Expand All @@ -181,6 +203,21 @@ public function disableMaintenance($mode = self::AUTO_MAINTENANCE)
$this->maintenanceMode = $mode;
}

public function disableMaintenanceNow($mode = self::AUTO_MAINTENANCE, bool $force = false): void
{
if (!$this->isMaintenanceMode()) {
return;
}

$path = $this->container->getParameter('eccube_content_maintenance_file_path');
$contents = file_get_contents($path);
$currentMode = explode(':', $contents)[0] ?? null;

if ($force || $currentMode === $mode) {
unlink($path);
}
}

/**
* メンテナンスモードの状態を判定する
*
Expand Down

0 comments on commit 1e947c0

Please sign in to comment.