Completed
Pull Request — master (#63)
by
unknown
14:53
created

ProtectAgainstSpam::shouldCheckHoneypot()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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