HumanVerification.php 5.26 KB
Newer Older
Dominik Hebeler's avatar
Dominik Hebeler committed
1
2
3
4
<?php

namespace App\Http\Middleware;

5
6
use Captcha;
use Carbon;
Dominik Hebeler's avatar
Dominik Hebeler committed
7
8
use Closure;
use DB;
9
use Illuminate\Http\Response;
Dominik Hebeler's avatar
Dominik Hebeler committed
10
11
12
13
14
15
16
17
18
19
20
21

class HumanVerification
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
        //try {
        $id = hash("sha512", $request->ip());
        $uid = hash("sha512", $request->ip() . $_SERVER["AGENT"]);
        unset($_SERVER["AGENT"]);

        /**
         * If the user sends a Password or a key
         * We will not verificate the user.
         * If someone that uses a bot finds this out we
         * might have to change it at some point.
         */
        if ($request->filled('password') || $request->filled('key') || $request->filled('appversion') || !env('BOT_PROTECTION', false)) {
            return $next($request);
        }

        // The specific user
        $user = DB::table('humanverification')->where('uid', $uid)->first();

        $createdAt = Carbon::now();
        $unusedResultPages = 1;
        $locked = false;
        # If this user doesn't have an entry we will create one

        if ($user === null) {
            DB::table('humanverification')->insert(
                [
                    'uid' => $uid,
                    'id' => $id,
                    'unusedResultPages' => 0,
                    'whitelist' => false,
                    'whitelistCounter' => 0,
                    'locked' => false,
                    "lockedKey" => "",
                    'updated_at' => Carbon::now(),
                ]
            );
            # Insert the URL the user tries to reach
            $url = url()->full();
            DB::table('usedurls')->insert(['uid' => $uid, 'id' => $id, 'eingabe' => $request->input('eingabe', '')]);
            $user = DB::table('humanverification')->where('uid', $uid)->first();
        }

        # If the user is locked we will force a Captcha validation
        if ($user->locked === 1) {
            $captcha = Captcha::create("default", true);
            DB::table('humanverification')->where('uid', $uid)->update(['lockedKey' => $captcha["key"]]);
            return
            new Response(
                view('humanverification.captcha')
                    ->with('title', "Bestätigung erforderlich")
                    ->with('id', $uid)
                    ->with('url', url()->full())
                    ->with('image', $captcha["img"])
            );
        }

        # Find out how many requests this IP has made
        $sum = DB::table('humanverification')->where('id', $id)->where('whitelist', false)->sum('unusedResultPages');
Dominik Hebeler's avatar
Dominik Hebeler committed
80

81
82
83
84
85
86
87
88
89
90
91
92
93
94
        // Defines if this is the only user using that IP Adress
        $alone = DB::table('humanverification')->where('id', $id)->count() === 1;

        $unusedResultPages = intval($user->unusedResultPages);
        $unusedResultPages++;

        if ($sum < 50 || $alone || $user->whitelist === 1) {
            # This IP doesn't need verification yet
            # The user currently isn't locked

            # We have different security gates:
            #   50, 75, 85, >=90 => Captcha validated Result Pages
            # If the user shows activity on our result page the counter will be deleted
            # Maybe I'll add a ban if the user reaches 100
95
            $locked = false;
96
97
            if ($unusedResultPages === 50 || $unusedResultPages === 75 || $unusedResultPages === 85 || $unusedResultPages >= 90) {
                $locked = true;
Dominik Hebeler's avatar
Dominik Hebeler committed
98
99
            }

100
101
102
103
104
            DB::table('humanverification')->where('uid', $uid)->update(['unusedResultPages' => $unusedResultPages, 'locked' => $locked]);
            # Insert the URL the user tries to reach
            DB::table('usedurls')->insert(['uid' => $uid, 'id' => $id, 'eingabe' => $request->input('eingabe', '')]);
        } else {
            $tmpId = md5($uid . date("d"));
Dominik Hebeler's avatar
Dominik Hebeler committed
105

106
107
108
109
110
111
112
113
            # If the parameter uid is correctly set we will allow access to the result page
            if ($request->input('uid', '') !== $tmpId) {
                DB::table('humanverification')->where('uid', $uid)->increment('whitelistCounter');
                if ($user->whitelistCounter >= 4) {
                    DB::table('humanverification')->where('uid', $uid)->update(['locked' => true]);
                }

                # This IP will need verification
114
115
                return
                new Response(
116
117
118
119
                    view('humanverification.whitelistVerification')
                        ->with('title', $request->input('eingabe', '') . " - MetaGer")
                        ->with('method', $request->method())
                        ->with('uid', md5($uid . date("d")))
120
                );
121
122
123
124
            } else {
                DB::table('humanverification')->where('uid', $uid)->update(['unusedResultPages' => $unusedResultPages]);
                # Insert the URL the user tries to reach
                DB::table('usedurls')->insert(['uid' => $uid, 'id' => $id, 'eingabe' => $request->input('eingabe', '')]);
125
            }
Dominik Hebeler's avatar
Dominik Hebeler committed
126
127
        }

128
129
130
131
        /* } catch (\Illuminate\Database\QueryException $e) {
        // Failure in contacting metager3.de
        }*/
        $request->request->add(['verification_id' => $uid, 'verification_count' => $unusedResultPages]);
Dominik Hebeler's avatar
Dominik Hebeler committed
132
133
134
        return $next($request);
    }
}