HumanVerification.php 9.06 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\Cache;
Dominik Hebeler's avatar
Dominik Hebeler committed
10 11 12 13
use Input;

class HumanVerification extends Controller
{
14
    const PREFIX = "humanverification";
15 16
    const EXPIRELONG = 60 * 60 * 24 * 14;
    const EXPIRESHORT = 60 * 60 * 72;
17

18
    public static function captcha(Request $request, Hasher $hasher, $id, $uid, $url = null)
19 20 21 22 23 24
    {
        if ($url != null) {
            $url = base64_decode(str_replace("<<SLASH>>", "/", $url));
        } else {
            $url = $request->input('url');
        }
Dominik Hebeler's avatar
Dominik Hebeler committed
25

26 27 28 29 30 31 32 33 34
        $userlist = Cache::get(HumanVerification::PREFIX . "." . $id, []);
        $user = null;

        if (sizeof($userlist) === 0 || empty($userlist[$uid])) {
            return redirect('/');
        } else {
            $user = $userlist[$uid];
        }

35
        if ($request->getMethod() == 'POST') {
36
            \App\PrometheusExporter::CaptchaAnswered();
37
            $lockedKey = $user["lockedKey"];
38 39
            $key = $request->input('captcha');
            $key = strtolower($key);
40

41
            if (!$hasher->check($key, $lockedKey)) {
42
                $captcha = Captcha::create("default", true);
43 44
                $user["lockedKey"] = $captcha["key"];
                HumanVerification::saveUser($user);
45
                \App\PrometheusExporter::CaptchaShown();
46
                return view('humanverification.captcha')->with('title', 'Bestätigung notwendig')
47
                    ->with('uid', $user["uid"])
48 49 50
                    ->with('id', $id)
                    ->with('url', $url)
                    ->with('image', $captcha["img"])
Dominik Hebeler's avatar
Dominik Hebeler committed
51
                    ->with('errorMessage', 'Fehler: Falsche Eingabe!');
52
            } else {
53
                \App\PrometheusExporter::CaptchaCorrect();
54
                # If we can unlock the Account of this user we will redirect him to the result page
55
                if ($user !== null && $user["locked"]) {
Dominik Hebeler's avatar
Dominik Hebeler committed
56
                    # The Captcha was correct. We can remove the key from the user
57 58 59 60 61
                    # Additionally we will whitelist him so he is not counted towards botnetwork
                    $user["locked"] = false;
                    $user["lockedKey"] = "";
                    $user["whitelist"] = true;
                    HumanVerification::saveUser($user);
Dominik Hebeler's avatar
Dominik Hebeler committed
62
                    return redirect($url);
63
                } else {
Dominik Hebeler's avatar
Dominik Hebeler committed
64 65 66 67
                    return redirect('/');
                }
            }
        }
68
        $captcha = Captcha::create("default", true);
69 70
        $user["lockedKey"] = $captcha["key"];
        HumanVerification::saveUser($user);
71
        \App\PrometheusExporter::CaptchaShown();
72
        return view('humanverification.captcha')->with('title', 'Bestätigung notwendig')
73
            ->with('uid', $user["uid"])
74 75 76
            ->with('id', $id)
            ->with('url', $url)
            ->with('image', $captcha["img"]);
Dominik Hebeler's avatar
Dominik Hebeler committed
77

Dominik Hebeler's avatar
Dominik Hebeler committed
78 79
    }

80 81 82
    public static function remove(Request $request)
    {
        if (!$request->has('mm')) {
Dominik Hebeler's avatar
Dominik Hebeler committed
83 84
            abort(404, "Keine Katze gefunden.");
        }
85

86
        if (HumanVerification::checkId($request, $request->input('mm'))) {
87
            HumanVerification::removeUser($request, $request->input('mm'));
Dominik Hebeler's avatar
Dominik Hebeler committed
88 89 90 91 92
        }
        return response(hex2bin('89504e470d0a1a0a0000000d494844520000000100000001010300000025db56ca00000003504c5445000000a77a3dda0000000174524e530040e6d8660000000a4944415408d76360000000020001e221bc330000000049454e44ae426082'), 200)
            ->header('Content-Type', 'image/png');
    }

93 94 95
    public static function removeGet(Request $request, $mm, $password, $url)
    {
        $url = base64_decode(str_replace("<<SLASH>>", "/", $url));
Dominik Hebeler's avatar
Dominik Hebeler committed
96 97
        # 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"));
Dominik Hebeler's avatar
Dominik Hebeler committed
98

99
        if (HumanVerification::checkId($request, $mm) && $requiredPass === $password) {
100
            HumanVerification::removeUser($request, $mm);
Dominik Hebeler's avatar
Dominik Hebeler committed
101 102 103 104
        }
        return redirect($url);
    }

105 106 107
    private static function saveUser($user)
    {
        $userList = Cache::get(HumanVerification::PREFIX . "." . $user["id"], []);
Dominik Hebeler's avatar
Dominik Hebeler committed
108
        
109 110 111 112 113
        if ($user["whitelist"]) {
            $user["expiration"] = now()->addWeeks(2);
        } else {
            $user["expiration"] = now()->addHours(72);
        }
Dominik Hebeler's avatar
Dominik Hebeler committed
114
        $userList[$user["uid"]] = $user;
115
        Cache::put(HumanVerification::PREFIX . "." . $user["id"], $userList, now()->addWeeks(2));
Dominik Hebeler's avatar
Dominik Hebeler committed
116
        dd($user);
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
    }

    private static function deleteUser($user)
    {
        $userList = Cache::get(HumanVerification::PREFIX . "." . $user["id"], []);
        $newUserList = [];
        $changed = false;

        foreach ($userList as $uid => $userTmp) {
            if ($userTmp["uid"] !== $user["uid"]) {
                $newUserList[$userTmp["uid"]] = $userTmp;
            } else {
                $changed = true;
            }
        }
Dominik Hebeler's avatar
Dominik Hebeler committed
132

133
        if ($changed) {
Dominik Hebeler's avatar
Dominik Hebeler committed
134 135 136 137 138
            if (sizeof($newUserList) > 0) {
                Cache::put(HumanVerification::PREFIX . "." . $user["id"], $newUserList, now()->addWeeks(2));
            } else {
                Cache::forget(HumanVerification::PREFIX . "." . $user["id"], $newUserList);
            }
139 140 141
        }
    }

142 143
    private static function removeUser($request, $uid)
    {
Dominik Hebeler's avatar
Dominik Hebeler committed
144 145
        $ip = $request->ip();
        $id = "";
Dominik Hebeler's avatar
Bugfix  
Dominik Hebeler committed
146
        if (HumanVerification::couldBeSpammer($ip)) {
Dominik Hebeler's avatar
Dominik Hebeler committed
147 148 149 150
            $id = hash("sha512", "999.999.999.999");
        } else {
            $id = hash("sha512", $ip);
        }
151

152 153 154 155 156 157 158
        $userlist = Cache::get(HumanVerification::PREFIX . "." . $id, []);
        $user = null;

        if (sizeof($userlist) === 0 || empty($userlist[$uid])) {
            return;
        } else {
            $user = $userlist[$uid];
159 160 161
        }

        $sum = 0;
162
        foreach ($userlist as $uidTmp => $userTmp) {
Dominik Hebeler's avatar
Dominik Hebeler committed
163
            if (!empty($userTmp) && gettype($userTmp["whitelist"]) === "boolean" && !$userTmp["whitelist"]) {
164 165
                $sum += intval($userTmp["unusedResultPages"]);
            }
166 167
        }
        # Check if we have to whitelist the user or if we can simply delete the data
168
        if ($user["unusedResultPages"] < $sum && !$user["whitelist"]) {
169
            # Whitelist
170
            $user["whitelist"] = true;
171 172
        }

173
        if ($user["whitelist"]) {
174 175
            $user["unusedResultPages"] = 0;
            HumanVerification::saveUser($user);
176
        } else {
177
            HumanVerification::deleteUser($user);
178 179 180
        }
    }

181 182
    private static function checkId($request, $id)
    {
Dominik Hebeler's avatar
Dominik Hebeler committed
183 184
        $uid = "";
        $ip = $request->ip();
Dominik Hebeler's avatar
Bugfix  
Dominik Hebeler committed
185
        if (HumanVerification::couldBeSpammer($ip)) {
Dominik Hebeler's avatar
Dominik Hebeler committed
186 187 188 189 190 191
            $uid = hash("sha512", "999.999.999.999" . $ip . $_SERVER["AGENT"] . "uid");
        } else {
            $uid = hash("sha512", $ip . $_SERVER["AGENT"] . "uid");
        }

        if ($uid === $id) {
Dominik Hebeler's avatar
Dominik Hebeler committed
192
            return true;
193
        } else {
Dominik Hebeler's avatar
Dominik Hebeler committed
194 195 196
            return false;
        }
    }
Dominik Hebeler's avatar
Dominik Hebeler committed
197

Dominik Hebeler's avatar
Bugfix  
Dominik Hebeler committed
198
    public static function couldBeSpammer($ip)
Dominik Hebeler's avatar
Dominik Hebeler committed
199
    {
Dominik Hebeler's avatar
Bugfix  
Dominik Hebeler committed
200 201 202 203 204 205
        $possibleSpammer = false;

        # Check for recent Spams
        $eingabe = \Request::input('eingabe');
        if (\preg_match("/^susimail\s+-site:[^\s]+\s-site:/si", $eingabe)) {
            return true;
Dominik Hebeler's avatar
Dominik Hebeler committed
206
        } else if (\preg_match("/^\s*site:\"linkedin\.com[^\"]*\"\s+/si", $eingabe)) {
Dominik Hebeler's avatar
Dominik Hebeler committed
207
            return true;
Dominik Hebeler's avatar
Bugfix  
Dominik Hebeler committed
208 209 210 211
        }

        return $possibleSpammer;

Dominik Hebeler's avatar
Dominik Hebeler committed
212
    }
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231

    public function botOverview(Request $request){
        $id = "";
        $uid = "";
        $ip = $request->ip();
        if (\App\Http\Controllers\HumanVerification::couldBeSpammer($ip)) {
            $id = hash("sha512", "999.999.999.999");
            $uid = hash("sha512", "999.999.999.999" . $ip . $_SERVER["AGENT"] . "uid");
        } else {
            $id = hash("sha512", $ip);
            $uid = hash("sha512", $ip . $_SERVER["AGENT"] . "uid");
        }

        $userList = Cache::get(HumanVerification::PREFIX . "." . $id);
        $user = $userList[$uid];

        return view('humanverification.botOverview')
            ->with('title', "Bot Overview")
            ->with('ip', $ip)
232
            ->with('userList', $userList)
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
            ->with('user', $user);
    }

    public function botOverviewChange(Request $request) {
        $id = "";
        $uid = "";
        $ip = $request->ip();
        if (\App\Http\Controllers\HumanVerification::couldBeSpammer($ip)) {
            $id = hash("sha512", "999.999.999.999");
            $uid = hash("sha512", "999.999.999.999" . $ip . $_SERVER["AGENT"] . "uid");
        } else {
            $id = hash("sha512", $ip);
            $uid = hash("sha512", $ip . $_SERVER["AGENT"] . "uid");
        }

        $userList = Cache::get(HumanVerification::PREFIX . "." . $id);
        $user = $userList[$uid];

        if($request->filled("locked")){
            $user["locked"] = boolval($request->input('locked'));
        }elseif($request->filled("whitelist")) {
            $user["whitelist"] = boolval($request->input('whitelist'));
        }elseif($request->filled("unusedResultPages")) {
            $user["unusedResultPages"] = intval($request->input('unusedResultPages'));
        }

        HumanVerification::saveUser($user);
        return redirect('admin/bot');
    }
Dominik Hebeler's avatar
Dominik Hebeler committed
262
}