ProtectAgainstSpam   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 6
dl 0
loc 84
rs 10
c 0
b 0
f 0

5 Methods

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