Passed
Push — master ( 61f080...c2fff9 )
by xu
04:40 queued 50s
created

ThrottleRequests::buildNeedAuthException()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
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\Exceptions\ToManyAttemptException;
18
use Godruoyi\Tencent007\Response as Tencent007Response;
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 (($cache = config('007.cache')) > 0 && $this->cache->has($key.':passed')) {
0 ignored issues
show
Bug introduced by
The property cache does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
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
            $ticket = $request->get(config('007.request_key_map.ticket', 'ticket'));
47
            $randstr = $request->get(config('007.request_key_map.randstr', 'randstr'));
48
49
            if (empty($ticket) || empty($randstr)) {
50
                return $this->buildNeedAuthException();
51
            }
52
53
            $checkResponse = Client::check($ticket, $randstr, $request->ip());
54
55
            if ($checkResponse->level() >= config('007.level', 70)) {
56
                return $this->buildNotPassedResponse($checkResponse);
57
            }
58
59
            $cache > 0 && $this->joinKeyToCache($key, $cache);
60
        }
61
62
        $this->hit($key, $decayMinutes);
63
64
        $response = $next($request);
65
66
        return $this->addHeaders(
67
            $response,
68
            $maxAttempts,
69
            $this->calculateRemainingAttempts($key, $maxAttempts)
70
        );
71
    }
72
73
    /**
74
     * Rewrite hit for subclass cover.
75
     *
76
     * @param string $key
77
     * @param int    $decayMinutes
78
     */
79
    protected function hit($key, $decayMinutes)
80
    {
81
        return $this->limiter->hit($key, $decayMinutes * 60);
82
    }
83
84
    /**
85
     * Build a Invalid Argument Exception.
86
     *
87
     * @return mixed
88
     */
89
    protected function buildNeedAuthException()
90
    {
91
        throw new NeedCaptchaAuthException();
92
    }
93
94
    /**
95
     * Build response from not passed.
96
     *
97
     * @param Tencent007Response $response
98
     *
99
     * @return mixed
100
     */
101
    protected function buildNotPassedResponse(Tencent007Response $response)
102
    {
103
        \Log::error('Tencent 007 not passed: '.$response->message());
104
105
        throw new RequestNotPassedException(403, $response->message());
106
    }
107
108
    /**
109
     * @param string $key
110
     * @param int    $hour
111
     */
112
    protected function joinKeyToCache($key, $hour)
113
    {
114
        $added = $this->cache->add($key.':passed', 1, $decayMinutes = ($hour * 60));
115
116
        if (!$added) {
117
            $this->cache->put($key.':passed', 1, $decayMinutes);
118
        }
119
    }
120
}
121