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

namespace App\Http\Controllers;

5
6
7
use Captcha;
use Carbon;
use Illuminate\Hashing\BcryptHasher as Hasher;
Dominik Hebeler's avatar
Dominik Hebeler committed
8
use Illuminate\Http\Request;
9
use Illuminate\Support\Facades\Redis;
Dominik Hebeler's avatar
Dominik Hebeler committed
10
11
12
13
use Input;

class HumanVerification extends Controller
{
14
15
    const PREFIX = "humanverification";

16
17
    public static function captcha(Request $request, Hasher $hasher, $id, $url = null)
    {
18

19
20
21
22
23
        if ($url != null) {
            $url = base64_decode(str_replace("<<SLASH>>", "/", $url));
        } else {
            $url = $request->input('url');
        }
Dominik Hebeler's avatar
Dominik Hebeler committed
24

25
26
        if ($request->getMethod() == 'POST') {

27
28
29
30
31
32
33
34
35
36
            $user = Redis::hgetall(HumanVerification::PREFIX . "." . $id);
            $user = ['uid' => $user["uid"],
                'id' => $user["id"],
                'unusedResultPages' => intval($user["unusedResultPages"]),
                'whitelist' => filter_var($user["whitelist"], FILTER_VALIDATE_BOOLEAN),
                'locked' => filter_var($user["locked"], FILTER_VALIDATE_BOOLEAN),
                "lockedKey" => $user["lockedKey"],
            ];

            $lockedKey = $user["lockedKey"];
37
38
            $key = $request->input('captcha');
            $key = strtolower($key);
39

40
41
            if (!$hasher->check($key, $lockedKey)) {
                $captcha = Captcha::create("default", true);
42
                Redis::hset(HumanVerification::PREFIX . "." . $id, 'lockedKey', $captcha["key"]);
43
                return view('humanverification.captcha')->with('title', 'Bestätigung notwendig')
44
45
46
                    ->with('id', $id)
                    ->with('url', $url)
                    ->with('image', $captcha["img"])
Dominik Hebeler's avatar
Dominik Hebeler committed
47
                    ->with('errorMessage', 'Fehler: Falsches Captcha eingegeben!');
48
49
            } else {
                # If we can unlock the Account of this user we will redirect him to the result page
50
                if ($user !== null && $user["locked"]) {
Dominik Hebeler's avatar
Dominik Hebeler committed
51
                    # The Captcha was correct. We can remove the key from the user
52
                    Redis::hmset(HumanVerification::PREFIX . "." . $id, ['locked' => "0", 'lockedKey' => ""]);
Dominik Hebeler's avatar
Dominik Hebeler committed
53
                    return redirect($url);
54
                } else {
Dominik Hebeler's avatar
Dominik Hebeler committed
55
56
57
58
                    return redirect('/');
                }
            }
        }
59
        $captcha = Captcha::create("default", true);
60
        Redis::hset(HumanVerification::PREFIX . "." . $id, 'lockedKey', $captcha["key"]);
61
        return view('humanverification.captcha')->with('title', 'Bestätigung notwendig')
62
63
64
            ->with('id', $id)
            ->with('url', $url)
            ->with('image', $captcha["img"]);
Dominik Hebeler's avatar
Dominik Hebeler committed
65

Dominik Hebeler's avatar
Dominik Hebeler committed
66
67
    }

68
69
70
    public static function remove(Request $request)
    {
        if (!$request->has('mm')) {
Dominik Hebeler's avatar
Dominik Hebeler committed
71
72
            abort(404, "Keine Katze gefunden.");
        }
73

74
        if (HumanVerification::checkId($request, $request->input('mm'))) {
75
            HumanVerification::removeUser($request, $request->input('mm'));
Dominik Hebeler's avatar
Dominik Hebeler committed
76
77
78
79
80
        }
        return response(hex2bin('89504e470d0a1a0a0000000d494844520000000100000001010300000025db56ca00000003504c5445000000a77a3dda0000000174524e530040e6d8660000000a4944415408d76360000000020001e221bc330000000049454e44ae426082'), 200)
            ->header('Content-Type', 'image/png');
    }

81
82
83
    public static function removeGet(Request $request, $mm, $password, $url)
    {
        $url = base64_decode(str_replace("<<SLASH>>", "/", $url));
Dominik Hebeler's avatar
Dominik Hebeler committed
84
85
86

        # If the user is correct and the password is we will delete any entry in the database
        $requiredPass = md5($mm . Carbon::NOW()->day . $url . env("PROXY_PASSWORD"));
87
        if (HumanVerification::checkId($request, $mm) && $requiredPass === $password) {
88
            HumanVerification::removeUser($request, $mm);
Dominik Hebeler's avatar
Dominik Hebeler committed
89
90
91
92
        }
        return redirect($url);
    }

93
94
95
96
    private static function removeUser($request, $uid)
    {
        $id = hash("sha512", $request->ip());

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
        $userList = Redis::smembers(HumanVerification::PREFIX . "." . $id);
        $pipe = Redis::pipeline();
        foreach ($userList as $userid) {
            $pipe->hgetall(HumanVerification::PREFIX . "." . $userid);
        }
        $usersData = $pipe->execute();

        $user = [];
        $users = [];
        $sum = 0;
        foreach ($usersData as $userTmp) {
            if (empty($userTmp)) {
                continue;
            }
            $userNew = ['uid' => $userTmp["uid"],
                'id' => $userTmp["id"],
                'unusedResultPages' => intval($userTmp["unusedResultPages"]),
                'whitelist' => filter_var($userTmp["whitelist"], FILTER_VALIDATE_BOOLEAN),
                'locked' => filter_var($userTmp["locked"], FILTER_VALIDATE_BOOLEAN),
                "lockedKey" => $userTmp["lockedKey"],
            ];

            if ($uid === $userTmp["uid"]) {
                $user = $userNew;
            } else {
                $users[] = $userNew;
            }
            if ($userNew["whitelist"]) {
                $sum += intval($userTmp["unusedResultPages"]);
            }

        }
129

130
        if (empty($user)) {
131
132
133
            return;
        }

134
        $pipeline = Redis::pipeline();
135
        # Check if we have to whitelist the user or if we can simply delete the data
136
        if ($user["unusedResultPages"] < $sum && !$user["whitelist"]) {
137
            # Whitelist
138
139
            $pipeline->hset(HumanVerification::PREFIX . "." . $uid, 'whitelist', "1");
            $user["whitelist"] = true;
140
141
        }

142
143
        if ($user["whitelist"]) {
            $pipeline->hset(HumanVerification::PREFIX . "." . $uid, 'unusedResultPages', "0");
144
        } else {
145
146
            $pipeline->hdel(HumanVerification::PREFIX . "." . $uid);
            $pipeline->srem(HumanVerification::PREFIX . "." . $id, $uid);
147
        }
148
        $pipeline->execute();
149
150
    }

151
152
    private static function checkId($request, $id)
    {
153
        if (hash("sha512", $request->ip() . $_SERVER["AGENT"]) === $id) {
Dominik Hebeler's avatar
Dominik Hebeler committed
154
            return true;
155
        } else {
Dominik Hebeler's avatar
Dominik Hebeler committed
156
157
158
159
            return false;
        }
    }
}