HumanVerification.php 9.02 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 232 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

    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)
            ->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
261
}