Skip to content
Snippets Groups Projects
Commit df1ace8e authored by Dominik Hebeler's avatar Dominik Hebeler
Browse files

Switched almost everything to Redis humanverification.

Tests need to be done!
parent ff7cc64c
No related branches found
No related tags found
3 merge requests!1393Development,!1390Development,!1387Resolve "Optimize Human Verification"
......@@ -31,13 +31,6 @@ class Kernel extends ConsoleKernel
DB::table('monthlyrequests')->truncate();
DB::disconnect('mysql');
})->monthlyOn(1, '00:00');
// Delete all of the old humanverification entries
$schedule->call(function () {
DB::delete('DELETE FROM humanverification WHERE updated_at < (now() - interval 72 hour) AND whitelist = 0 ORDER BY updated_at DESC');
DB::delete('DELETE FROM humanverification WHERE updated_at < (now() - interval 2 week) AND whitelist = 1 ORDER BY updated_at DESC');
DB::disconnect('mysql');
})->everyThirtyMinutes();
}
/**
......
......@@ -4,15 +4,18 @@ namespace App\Http\Controllers;
use Captcha;
use Carbon;
use DB;
use Illuminate\Hashing\BcryptHasher as Hasher;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;
use Input;
class HumanVerification extends Controller
{
const PREFIX = "humanverification";
public static function captcha(Request $request, Hasher $hasher, $id, $url = null)
{
if ($url != null) {
$url = base64_decode(str_replace("<<SLASH>>", "/", $url));
} else {
......@@ -20,15 +23,23 @@ class HumanVerification extends Controller
}
if ($request->getMethod() == 'POST') {
$user = DB::table('humanverification')->where('uid', $id)->first();
$lockedKey = $user->lockedKey;
$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"];
$key = $request->input('captcha');
$key = strtolower($key);
if (!$hasher->check($key, $lockedKey)) {
$captcha = Captcha::create("default", true);
DB::table('humanverification')->where('uid', $id)->update(['lockedKey' => $captcha["key"]]);
Redis::hset(HumanVerification::PREFIX . "." . $id, 'lockedKey', $captcha["key"]);
return view('humanverification.captcha')->with('title', 'Bestätigung notwendig')
->with('id', $id)
->with('url', $url)
......@@ -36,9 +47,9 @@ class HumanVerification extends Controller
->with('errorMessage', 'Fehler: Falsches Captcha eingegeben!');
} else {
# If we can unlock the Account of this user we will redirect him to the result page
if ($user !== null && $user->locked === 1) {
if ($user !== null && $user["locked"]) {
# The Captcha was correct. We can remove the key from the user
DB::table('humanverification')->where('uid', $id)->update(['locked' => false, 'lockedKey' => "", 'whitelist' => 1]);
Redis::hmset(HumanVerification::PREFIX . "." . $id, ['locked' => "0", 'lockedKey' => ""]);
return redirect($url);
} else {
return redirect('/');
......@@ -46,7 +57,7 @@ class HumanVerification extends Controller
}
}
$captcha = Captcha::create("default", true);
DB::table('humanverification')->where('uid', $id)->update(['lockedKey' => $captcha["key"]]);
Redis::hset(HumanVerification::PREFIX . "." . $id, 'lockedKey', $captcha["key"]);
return view('humanverification.captcha')->with('title', 'Bestätigung notwendig')
->with('id', $id)
->with('url', $url)
......@@ -83,28 +94,58 @@ class HumanVerification extends Controller
{
$id = hash("sha512", $request->ip());
$sum = DB::table('humanverification')->where('id', $id)->where('whitelist', false)->sum('unusedResultPages');
$user = DB::table('humanverification')->where('uid', $uid)->first();
$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"]);
}
}
if ($user === null) {
if (empty($user)) {
return;
}
$pipeline = Redis::pipeline();
# Check if we have to whitelist the user or if we can simply delete the data
if ($user->unusedResultPages < $sum && $user->whitelist === 0) {
if ($user["unusedResultPages"] < $sum && !$user["whitelist"]) {
# Whitelist
DB::table('humanverification')->where('uid', $uid)->update(['whitelist' => true, 'whitelistCounter' => 0]);
$user->whitelist = 1;
$user->whitelistCounter = 0;
$pipeline->hset(HumanVerification::PREFIX . "." . $uid, 'whitelist', "1");
$user["whitelist"] = true;
}
if ($user->whitelist === 1) {
DB::table('humanverification')->where('uid', $uid)->update(['unusedResultPages' => 0]);
if ($user["whitelist"]) {
$pipeline->hset(HumanVerification::PREFIX . "." . $uid, 'unusedResultPages', "0");
} else {
DB::table('humanverification')->where('uid', $uid)->where('updated_at', '<', Carbon::NOW()->subSeconds(2))->delete();
$pipeline->hdel(HumanVerification::PREFIX . "." . $uid);
$pipeline->srem(HumanVerification::PREFIX . "." . $id, $uid);
}
$pipeline->execute();
}
private static function checkId($request, $id)
......
......@@ -12,7 +12,6 @@ class MetaGerSearch extends Controller
{
public function search(Request $request, MetaGer $metager)
{
$focus = $request->input("focus", "web");
if ($focus === "maps") {
......
......@@ -3,10 +3,9 @@
namespace App\Http\Middleware;
use Captcha;
use Carbon;
use Closure;
use DB;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Redis;
use URL;
class HumanVerification
......@@ -22,8 +21,8 @@ class HumanVerification
{
// The specific user
$user = null;
$newUser = true;
$update = true;
$prefix = "humanverification";
try {
$id = hash("sha512", $request->ip());
$uid = hash("sha512", $request->ip() . $_SERVER["AGENT"]);
......@@ -40,42 +39,54 @@ class HumanVerification
return $next($request);
}
$users = DB::select('select * from humanverification where id = ?', [$id]);
# Get all Users of this IP
$userList = Redis::smembers($prefix . "." . $id);
$pipe = Redis::pipeline();
foreach ($userList as $userid) {
$pipe->hgetall($prefix . "." . $userid);
}
$usersData = $pipe->execute();
$user = [];
$users = [];
# Lock out everyone in a Bot network
# Find out how many requests this IP has made
$sum = 0;
foreach ($users as $userTmp) {
if ($uid == $userTmp->uid) {
$user = ['uid' => $userTmp->uid,
'id' => $userTmp->id,
'unusedResultPages' => intval($userTmp->unusedResultPages),
'whitelist' => filter_var($userTmp->whitelist, FILTER_VALIDATE_BOOLEAN),
'whitelistCounter' => $userTmp->whitelistCounter,
'locked' => filter_var($userTmp->locked, FILTER_VALIDATE_BOOLEAN),
"lockedKey" => $userTmp->lockedKey,
'updated_at' => Carbon::now(),
];
$newUser = false;
foreach ($usersData as $userTmp) {
if (empty($userTmp)) {
continue;
}
if ($userTmp->whitelist === 0) {
$sum += $userTmp->unusedResultPages;
$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"]);
}
}
# If this user doesn't have an entry we will create one
if ($user === null) {
# If this user doesn't have an entry we will create one
if (empty($user)) {
$user =
[
'uid' => $uid,
'id' => $id,
'unusedResultPages' => 0,
'whitelist' => false,
'whitelistCounter' => 0,
'locked' => false,
"lockedKey" => "",
'updated_at' => Carbon::now(),
];
}
......@@ -96,7 +107,7 @@ class HumanVerification
// Defines if this is the only user using that IP Adress
$alone = true;
foreach ($users as $userTmp) {
if ($userTmp->uid != $uid && !$userTmp->whitelist) {
if ($userTmp["uid"] != $uid && !$userTmp["whitelist"]) {
$alone = false;
}
......@@ -133,41 +144,33 @@ class HumanVerification
}
}
} catch (\Illuminate\Database\QueryException $e) {
// Failure in contacting metager3.de
} catch (\Predis\Connection\ConnectionException $e) {
$update = false;
} finally {
if ($update) {
// Update the user in the database
if ($newUser) {
DB::table('humanverification')->insert(
[
'uid' => $user["uid"],
'id' => $user["id"],
'unusedResultPages' => $user['unusedResultPages'],
'whitelist' => $user["whitelist"],
'whitelistCounter' => $user["whitelistCounter"],
'locked' => $user["locked"],
"lockedKey" => $user["lockedKey"],
'updated_at' => $user["updated_at"],
]
);
$pipeline = Redis::pipeline();
$pipeline->hmset($prefix . "." . $user['uid'], $user);
$pipeline->sadd($prefix . "." . $user["id"], $user["uid"]);
$expireDate = now();
$expireDateLong = date_add($expireDate, date_interval_create_from_date_string('2 weeks'))->timestamp;
$expireDateShort = date_add($expireDate, date_interval_create_from_date_string('2 weeks'))->timestamp;
if ($user["whitelist"]) {
$pipeline->expireat($prefix . "." . $user['uid'], $expireDateLong);
} else {
DB::table('humanverification')->where('uid', $uid)->update(
[
'uid' => $user["uid"],
'id' => $user["id"],
'unusedResultPages' => $user['unusedResultPages'],
'whitelist' => $user["whitelist"],
'whitelistCounter' => $user["whitelistCounter"],
'locked' => $user["locked"],
"lockedKey" => $user["lockedKey"],
'updated_at' => $user["updated_at"],
]
);
$pipeline->expireat($prefix . "." . $user['uid'], $expireDateShort);
}
$pipeline->expireat($prefix . "." . $user["id"], $expireDateLong);
$pipeline->execute();
}
DB::disconnect('mysql');
}
$request->request->add(['verification_id' => $user["uid"], 'verification_count' => $user["unusedResultPages"]]);
return $next($request);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment