Completed
Push — master ( 0385f3...5259bf )
by Ruben
01:50 queued 43s
created

ProtectAgainstSpam::shouldCheckHoneypot()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 2
1
<?php
2
3
namespace Spatie\Honeypot;
4
5
use Closure;
6
use Exception;
7
use Illuminate\Http\Request;
8
use Illuminate\Support\Str;
9
use Spatie\Honeypot\SpamResponder\SpamResponder;
10
use Symfony\Component\HttpFoundation\Response;
11
12
class ProtectAgainstSpam
13
{
14
    /** @var \Spatie\Honeypot\SpamResponder\SpamResponder */
15
    protected $spamResponder;
16
17
    public function __construct(SpamResponder $spamResponder)
18
    {
19
        $this->spamResponder = $spamResponder;
20
    }
21
22
    public function handle(Request $request, Closure $next): Response
23
    {
24
        if (! config('honeypot.enabled')) {
25
            return $next($request);
26
        }
27
28
        if (! $request->isMethod('POST')) {
29
            return $next($request);
30
        }
31
32
        $nameFieldName = config('honeypot.name_field_name');
33
34
        if (config('honeypot.randomize_name_field_name')) {
35
            $nameFieldName = $this->getRandomizedNameFieldName($nameFieldName, $request->all());
36
        }
37
38
        if (! $this->shouldCheckHoneypot($request, $nameFieldName)) {
39
            return $next($request);
40
        }
41
42
        if (! $request->has($nameFieldName)) {
43
            return $this->respondToSpam($request, $next);
44
        }
45
46
        $honeypotValue = $request->get($nameFieldName);
47
48
        if (! empty($honeypotValue)) {
49
            return $this->respondToSpam($request, $next);
50
        }
51
52
        $validFrom = $request->get(config('honeypot.valid_from_field_name'));
53
54
        if (! $validFrom) {
55
            return $this->respondToSpam($request, $next);
56
        }
57
58
        try {
59
            $time = new EncryptedTime($validFrom);
60
        } catch (Exception $decryptException) {
61
            $time = null;
62
        }
63
64
        if (! $time || $time->isFuture()) {
65
            return $this->respondToSpam($request, $next);
66
        }
67
68
        return $next($request);
69
    }
70
71
    private function getRandomizedNameFieldName($nameFieldName, $requestFields): ?String
72
    {
73
        return collect($requestFields)->filter(function ($value, $key) use ($nameFieldName) {
74
            return Str::startsWith($key, $nameFieldName);
75
        })->keys()->first();
76
    }
77
78
    protected function respondToSpam(Request $request, Closure $next): Response
79
    {
80
        event(new SpamDetected($request));
81
82
        return $this->spamResponder->respond($request, $next);
83
    }
84
85
    private function shouldCheckHoneypot(Request $request, ?string $nameFieldName): bool
86
    {
87
        if (config('honeypot.honeypot_fields_required_for_all_forms') == true) {
88
            return true;
89
        }
90
91
        return $request->has($nameFieldName) || $request->has(config('honeypot.valid_from_field_name'));
92
    }
93
}
94