Failed Conditions
Pull Request — 4.0 (#4910)
by
unknown
05:39
created

MaintenanceListener::onRequest()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 4
nop 1
dl 0
loc 24
rs 9.2248
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.ec-cube.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube\EventListener;
15
16
use Eccube\Entity\Member;
17
use Eccube\Request\Context;
18
use Eccube\Service\SystemService;
19
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
20
use Symfony\Component\HttpFoundation\Request;
21
use Symfony\Component\HttpFoundation\Response;
22
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
23
use Symfony\Component\HttpKernel\KernelEvents;
24
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
25
26
final class MaintenanceListener implements EventSubscriberInterface
27
{
28
    private const SESSION_KEY = '_security_admin';
29
30
    /** @var Context */
31
    private $context;
32
33
    /** @var SystemService */
34
    private $systemService;
35
36
    public function __construct(Context $context, SystemService $systemService)
37
    {
38
        $this->context = $context;
39
        $this->systemService = $systemService;
40
    }
41
42
    public static function getSubscribedEvents()
43
    {
44
        return [
45
            KernelEvents::REQUEST => 'onRequest',
46
        ];
47
    }
48
49
    public function onRequest(GetResponseEvent $event)
50
    {
51
        if (!$event->isMasterRequest()) {
52
            return;
53
        }
54
55
        if ($this->context->isAdmin() || !$this->systemService->isMaintenanceMode()) {
56
            return;
57
        }
58
59
        $request = $event->getRequest();
60
        if ($this->isAdminAuthenticated($request)) {
61
            return;
62
        }
63
64
        $locale = \env('ECCUBE_LOCALE');
65
        $templateCode = \env('ECCUBE_TEMPLATE_CODE');
66
        $baseUrl = htmlspecialchars(\rawurldecode($request->getBaseUrl()), ENT_QUOTES);
67
68
        \ob_start();
69
        require __DIR__ . '/../../../maintenance.php';
70
        $response = new Response(\ob_get_clean(), 503);
71
        $event->setResponse($response);
72
    }
73
74
    private function isAdminAuthenticated(Request $request): bool
75
    {
76
        $session = $request->hasPreviousSession() ? $request->getSession() : null;
77
78
        if ($session === null || ($serializedToken = $session->get(self::SESSION_KEY)) === null) {
79
            return false;
80
        }
81
82
        $unserializedToken = $this->safelyUnserialize($serializedToken);
83
        $user = ($unserializedToken instanceof TokenInterface)
84
            ? $unserializedToken->getUser()
85
            : null;
86
87
        return $user instanceof Member;
88
    }
89
90
    private function safelyUnserialize($serializedToken)
91
    {
92
        $e = $token = null;
93
        $prevUnserializeHandler = \ini_set('unserialize_callback_func', __CLASS__ . '::handleUnserializeCallback');
94
        $prevErrorHandler = \set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$prevErrorHandler) {
0 ignored issues
show
Unused Code introduced by
$prevErrorHandler is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
95
            if (__FILE__ === $file) {
96
                throw new \UnexpectedValueException($msg, 0x37313bc);
97
            }
98
99
            return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false;
100
        });
101
102
        try {
103
            $token = \unserialize($serializedToken);
104
        } catch (\Error $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
105
        } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
106
        }
107
        \restore_error_handler();
108
        \ini_set('unserialize_callback_func', $prevUnserializeHandler);
109
        if ($e) {
110
            if (!$e instanceof \UnexpectedValueException || 0x37313bc !== $e->getCode()) {
111
                throw $e;
112
            }
113
        }
114
115
        return $token;
116
    }
117
118
    /**
119
     * @internal
120
     */
121
    public static function handleUnserializeCallback($class)
122
    {
123
        throw new \UnexpectedValueException('Class not found: ' . $class, 0x37313bc);
124
    }
125
}
126