RateLimitListener   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 75
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 10
eloc 28
c 1
b 0
f 0
dl 0
loc 75
ccs 28
cts 28
cp 1
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A onKernelRequest() 0 23 6
A __construct() 0 6 1
A createRateLimitExceededException() 0 13 3
1
<?php
2
3
/*
4
 * This file is part of the ApiRateLimitBundle
5
 *
6
 * (c) Indra Gunawan <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Indragunawan\ApiRateLimitBundle\EventListener;
13
14
use Indragunawan\ApiRateLimitBundle\Exception\RateLimitExceededException;
15
use Indragunawan\ApiRateLimitBundle\Service\RateLimitHandler;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\HttpKernel\Event\RequestEvent;
18
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
19
20
/**
21
 * @author Indra Gunawan <[email protected]>
22
 */
23
class RateLimitListener
24
{
25
    /**
26
     * @var bool
27
     */
28
    private $enabled;
29
30
    /**
31
     * @var RateLimitHandler
32
     */
33
    private $rateLimitHandler;
34
35
    /**
36
     * @var array
37
     */
38
    private $exceptionConfig;
39
40
    /**
41
     * @var TokenStorageInterface
42
     */
43
    private $tokenStorage;
44
45 6
    public function __construct(bool $enabled, RateLimitHandler $rateLimitHandler, array $exceptionConfig, TokenStorageInterface $tokenStorage)
46
    {
47 6
        $this->enabled = $enabled;
48 6
        $this->rateLimitHandler = $rateLimitHandler;
49 6
        $this->exceptionConfig = $exceptionConfig;
50 6
        $this->tokenStorage = $tokenStorage;
51 6
    }
52
53 6
    public function onKernelRequest(RequestEvent $event)
54
    {
55 6
        if (!$this->enabled) {
56 1
            return;
57
        }
58
59
        // only process on master request
60 5
        if (!$event->isMasterRequest()) {
61 1
            return;
62
        }
63
64 4
        $request = $event->getRequest();
65 4
        if (!$request->attributes->has('_api_resource_class')) {
66 1
            return;
67
        }
68
69 3
        $this->rateLimitHandler->handle($request);
70
71 3
        if ($this->rateLimitHandler->isEnabled()) {
72 2
            $request->attributes->set('_api_rate_limit_info', $this->rateLimitHandler->getRateLimitInfo());
73
74 2
            if ($this->rateLimitHandler->isRateLimitExceeded()) {
75 2
                throw $this->createRateLimitExceededException($request);
76
            }
77
        }
78 1
    }
79
80
    /**
81
     * Returns an RateLimitExceededException.
82
     *
83
     * @return RateLimitExceededException
84
     */
85 2
    protected function createRateLimitExceededException(Request $request)
86
    {
87 2
        $config = $this->exceptionConfig;
88 2
        $class = $config['custom_exception'] ?? RateLimitExceededException::class;
89 2
        $username = null;
90
91 2
        if (null !== $token = $this->tokenStorage->getToken()) {
92 1
            if (\is_object($token->getUser())) {
93 1
                $username = $token->getUsername();
94
            }
95
        }
96
97 2
        return new $class($config['status_code'], $config['message'], $request->getClientIp(), $username);
98
    }
99
}
100