Passed
Push — trunk ( a9c8a1...b40967 )
by Christian
12:25 queued 12s
created

MaintenanceModeResolver::shouldBeCached()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 2
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Storefront\Framework\Routing;
4
5
use Shopware\Core\SalesChannelRequest;
6
use Symfony\Component\HttpFoundation\IpUtils;
7
use Symfony\Component\HttpFoundation\Request;
8
use Symfony\Component\HttpFoundation\RequestStack;
9
10
class MaintenanceModeResolver
11
{
12
    /**
13
     * @var RequestStack
14
     */
15
    protected $requestStack;
16
17
    /**
18
     * @internal
19
     */
20
    public function __construct(RequestStack $requestStack)
21
    {
22
        $this->requestStack = $requestStack;
23
    }
24
25
    /**
26
     * shouldRedirect returns true, when the given request should be redirected to the maintenance page.
27
     * This would be the case, for example, when the maintenance mode is active and the client's IP address
28
     * is not listed in the maintenance mode whitelist.
29
     */
30
    public function shouldRedirect(Request $request): bool
31
    {
32
        return $this->isSalesChannelRequest($this->requestStack->getMainRequest())
33
            && !$this->isMaintenancePageRequest($request)
34
            && !$this->isXmlHttpRequest($request)
35
            && !$this->isErrorControllerRequest($request)
36
            && $this->isMaintenanceRequest($request);
37
    }
38
39
    /**
40
     * shouldRedirectToShop returns true, when the given request to the maintenance page should be redirected to the shop.
41
     * This would be the case, for example, when the maintenance mode is not active or if it is active
42
     * the client's IP address is listed in the maintenance mode whitelist.
43
     */
44
    public function shouldRedirectToShop(Request $request): bool
45
    {
46
        return !$this->isXmlHttpRequest($request)
47
            && !$this->isErrorControllerRequest($request)
48
            && !$this->isMaintenanceRequest($request);
49
    }
50
51
    public function shouldBeCached(Request $request): bool
52
    {
53
        return !$this->isMaintenanceModeActive($request) || !$this->isClientAllowed($request);
54
    }
55
56
    /**
57
     * isMaintenanceRequest returns true, when the maintenance mode is active and the client's IP address
58
     * is not listed in the maintenance mode whitelist.
59
     */
60
    public function isMaintenanceRequest(Request $request): bool
61
    {
62
        return $this->isMaintenanceModeActive($request) && !$this->isClientAllowed($request);
63
    }
64
65
    private function isSalesChannelRequest(?Request $master): bool
66
    {
67
        if (!$master) {
68
            return false;
69
        }
70
71
        return (bool) $master->attributes->get(SalesChannelRequest::ATTRIBUTE_IS_SALES_CHANNEL_REQUEST);
72
    }
73
74
    private function isMaintenancePageRequest(Request $request): bool
75
    {
76
        if ($request->attributes->getBoolean(SalesChannelRequest::ATTRIBUTE_IS_ALLOWED_IN_MAINTENANCE)) {
77
            return true;
78
        }
79
80
        return false;
81
    }
82
83
    private function isXmlHttpRequest(Request $request): bool
84
    {
85
        return $request->isXmlHttpRequest();
86
    }
87
88
    private function isErrorControllerRequest(Request $request): bool
89
    {
90
        return $request->attributes->get('_route') === null
91
            && $request->attributes->get('_controller') === 'error_controller';
92
    }
93
94
    private function isMaintenanceModeActive(?Request $master): bool
95
    {
96
        if (!$master) {
97
            return false;
98
        }
99
100
        return (bool) $master->attributes->get(SalesChannelRequest::ATTRIBUTE_SALES_CHANNEL_MAINTENANCE);
101
    }
102
103
    private function isClientAllowed(Request $request): bool
104
    {
105
        return IpUtils::checkIp(
106
            (string) $request->getClientIp(),
107
            $this->getMaintenanceWhitelist($this->requestStack->getMainRequest())
108
        );
109
    }
110
111
    private function getMaintenanceWhitelist(?Request $master): array
112
    {
113
        if (!$master) {
114
            return [];
115
        }
116
117
        $whitelist = $master->attributes->get(SalesChannelRequest::ATTRIBUTE_SALES_CHANNEL_MAINTENANCE_IP_WHITLELIST);
118
119
        if (!$whitelist) {
120
            return [];
121
        }
122
123
        return json_decode($whitelist, true) ?? [];
124
    }
125
}
126