Passed
Push — master ( 5aefb3...3fe1f1 )
by xu
08:56
created

ThrottleRequests::handle()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 0
cts 19
cp 0
rs 9.52
c 0
b 0
f 0
cc 4
nc 3
nop 4
crap 20
1
<?php
2
3
/*
4
 * This file is part of the godruoyi/laravel-tencent007-captcha.
5
 *
6
 * (c) Godruoyi <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled.
9
 */
10
11
namespace Godruoyi\Tencent007\Middlewares;
12
13
use Closure;
14
use Godruoyi\Tencent007\Client;
15
use Godruoyi\Tencent007\Exceptions\NeedCaptchaAuthException;
16
use Godruoyi\Tencent007\Exceptions\RequestNotPassedException;
17
use Godruoyi\Tencent007\Response as Tencent007Response;
18
use Illuminate\Contracts\Cache\Repository as Cache;
19
use Illuminate\Routing\Middleware\ThrottleRequests as BaseThrottleRequests;
20
21
class ThrottleRequests extends BaseThrottleRequests
22
{
23
    /**
24
     * Handle an incoming request.
25
     *
26
     * @param \Illuminate\Http\Request $request
27
     * @param \Closure                 $next
28
     * @param int|string               $maxAttempts
29
     * @param float|int                $decayMinutes
30
     *
31
     * @return mixed
32
     *
33
     * @throws \Symfony\Component\HttpKernel\Exception\HttpException
34
     */
35
    public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1)
36
    {
37
        $key = $this->resolveRequestSignature($request);
38
39
        if ($this->existsInCacheForRequest($key, $request)) {
40
            return $next($request);
41
        }
42
43
        $maxAttempts = $this->resolveMaxAttempts($request, $maxAttempts);
44
45
        if ($this->limiter->tooManyAttempts($key, $maxAttempts, $decayMinutes)
0 ignored issues
show
Unused Code introduced by
The call to RateLimiter::tooManyAttempts() has too many arguments starting with $decayMinutes.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
46
            && ($response = $this->processTooManyAttempts())) {
0 ignored issues
show
Bug introduced by
The call to processTooManyAttempts() misses a required argument $request.

This check looks for function calls that miss required arguments.

Loading history...
47
            return $response;
48
        }
49
50
        $this->hit($key, $decayMinutes);
51
52
        $response = $next($request);
53
54
        return $this->addHeaders(
55
            $response,
56
            $maxAttempts,
57
            $this->calculateRemainingAttempts($key, $maxAttempts)
58
        );
59
    }
60
61
    /**
62
     * Process too many request.
63
     *
64
     * @param \Illuminate\Http\Request $request
65
     *
66
     * @return \Illuminate\Http\Response|mixed|null
67
     */
68
    protected function processTooManyAttempts($request)
69
    {
70
        $ticket = $request->get(config('007.request_key_map.ticket', 'ticket'));
71
        $randstr = $request->get(config('007.request_key_map.randstr', 'randstr'));
72
73
        if (empty($ticket) || empty($randstr)) {
74
            return $this->buildNeedAuthException();
75
        }
76
77
        $checkResponse = Client::check($ticket, $randstr, $request->ip());
78
79
        if ($checkResponse->level() >= config('007.level', 70)) {
80
            return $this->buildNotPassedResponse($checkResponse);
81
        }
82
83
        config('007.cache') > 0 && $this->joinKeyToCache($key, config('007.cache'));
0 ignored issues
show
Bug introduced by
The variable $key does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
84
    }
85
86
    /**
87
     * Exists in cache for current request.
88
     *
89
     * @param string                   $key
90
     * @param \Illuminate\Http\Request $request
91
     *
92
     * @return bool
93
     */
94
    protected function existsInCacheForRequest($key, $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
95
    {
96
        return config('007.cache') > 0 && app(Cache::class)->has($key.':passed');
97
    }
98
99
    /**
100
     * Rewrite hit for subclass cover.
101
     *
102
     * @param string $key
103
     * @param int    $decayMinutes
104
     */
105
    protected function hit($key, $decayMinutes)
106
    {
107
        return $this->limiter->hit($key, $decayMinutes);
108
    }
109
110
    /**
111
     * Build a Invalid Argument Exception.
112
     *
113
     * @return mixed
114
     */
115
    protected function buildNeedAuthException()
116
    {
117
        throw new NeedCaptchaAuthException();
118
    }
119
120
    /**
121
     * Build response from not passed.
122
     *
123
     * @param Tencent007Response $response
124
     *
125
     * @return mixed
126
     */
127
    protected function buildNotPassedResponse(Tencent007Response $response)
128
    {
129
        throw new RequestNotPassedException($response);
130
    }
131
132
    /**
133
     * @param string $key
134
     * @param int    $hour
135
     */
136
    protected function joinKeyToCache($key, $hour)
137
    {
138
        $added = app(Cache::class)->add($key.':passed', 1, $decayMinutes = ($hour * 60));
139
140
        if (!$added) {
141
            app(Cache::class)->put($key.':passed', 1, $decayMinutes);
142
        }
143
    }
144
}
145