Commit ee6f87e2 authored by Dominik Hebeler's avatar Dominik Hebeler
Browse files

added cookie option to captcha

parent 768463fe
......@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Models\Verification\CookieVerification;
use App\Models\Verification\HumanVerification as ModelsHumanVerification;
use Captcha;
use Carbon;
......@@ -11,6 +12,7 @@ use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
use Input;
use Laravel\SerializableClosure\Signers\Hmac;
class HumanVerification extends Controller
{
......@@ -71,8 +73,16 @@ class HumanVerification extends Controller
"url" => $redirect_url,
"e" => "",
];
if ($request->has("dnaa")) {
$params["dnaa"] = true;
}
return redirect(route('captcha_show', $params));
} else {
// Check if the user wants to store a cookie
if ($request->has("dnaa")) {
CookieVerification::createCookie();
}
\App\PrometheusExporter::CaptchaCorrect();
# Generate a token that makes the user skip Humanverification
# There are some special cases where a user that entered a correct Captcha
......
......@@ -37,6 +37,7 @@ class Kernel extends HttpKernel
'humanverification_routes' => [
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
],
'api' => [
......
<?php
namespace App\Models\Verification;
use Carbon;
use Cookie;
use Exception;
class CookieVerification extends Verification
{
const COOKIE_NAME = "hv_key";
const EXPIRATION_FORMAT = "Y-m-d H:i:s";
public function __construct($hv_key = null)
{
$this->cache_prefix = "humanverification.cookie";
if (empty($hv_key)) {
$hv_key = self::getKeyFromCookie();
if (empty($hv_key)) {
throw new Exception("Cannot find Cookie");
}
}
parent::__construct($hv_key, $hv_key);
}
public static function impersonate($id, $uid)
{
return new CookieVerification($id, $uid);
}
public static function getKeyFromCookie()
{
if (!Cookie::has(self::COOKIE_NAME)) {
return null;
}
$hv_data = Cookie::get(self::COOKIE_NAME);
$hv_data = \base64_decode($hv_data);
if (!$hv_data) {
return null;
}
$hv_data = \json_decode($hv_data);
if ($hv_data === null) {
return null;
}
if (empty($hv_data->expiration) || empty($hv_data->key) || empty($hv_data->verification)) {
return null;
}
// Check authenticity of Cookie
$required_hash = \hash_hmac("sha256", $hv_data->expiration . $hv_data->key, config("metager.metager.proxy.password"));
if (!\hash_equals($required_hash, $hv_data->verification)) {
return null;
}
// Check if Cookie is expired
$expiration = Carbon::createFromFormat(self::EXPIRATION_FORMAT, $hv_data->expiration);
if ($expiration < now()) {
return null;
}
return $hv_data->key;
}
public static function createCookie()
{
$expiration = now()->addMonths(1);
$key = \md5(\microtime(true));
$hv_data = [
"expiration" => $expiration->format(self::EXPIRATION_FORMAT),
"key" => $key,
"verification" => \hash_hmac("sha256", $expiration->format(self::EXPIRATION_FORMAT) . $key, config("metager.metager.proxy.password")),
];
Cookie::queue("hv_key", base64_encode(json_encode($hv_data)), $expiration->diffInMinutes(now()), "/", null, true, true);
}
}
......@@ -3,6 +3,7 @@
namespace App\Models\Verification;
use Cache;
use Exception;
class HumanVerification
{
......@@ -12,8 +13,13 @@ class HumanVerification
public function __construct()
{
$this->verificators[] = new IPVerification();
$this->verificators[] = new AgentVerification();
try {
$cookie_verificator = new CookieVerification();
$this->verificators[] = $cookie_verificator;
} catch (Exception $e) {
$this->verificators[] = new IPVerification();
$this->verificators[] = new AgentVerification();
}
$this->key = \md5("hv.key." . microtime(true));
$ids = [];
......
<?php
return [
'1' => 'Entschuldigen Sie die Störung',
'1' => 'Sicherheitsabfrage',
'2' => 'Bitte geben Sie die 5 Zeichen aus dem Bild in die Eingabebox und bestätigen Sie mit "OK" um zur Ergebnisseite zu gelangen.',
'3' => 'Captcha eingeben',
'4' => 'Auf diesem Gerät nicht erneut fragen (optional; setzt einen Cookie)',
];
......@@ -3,4 +3,5 @@ return [
'1' => 'Sorry to bother you',
'2' => 'Please enter the five characters from the picture in the input box and confirm with "OK" to get to the result page.',
'3' => 'Enter captcha',
'4' => 'Do not ask again on this device (optional; sets a cookie)',
];
......@@ -3,4 +3,5 @@ return [
'1' => 'Perdon por la molestia',
'2' => 'Ingrese los cinco caracteres de la imagen en el cuadro de entrada y confirme con "OK" para llegar a la página de resultados.',
'3' => 'Entrar en captcha',
'4' => 'No volver a preguntar en este dispositivo (opcional, establece una cookie)',
];
......@@ -7,4 +7,16 @@
max-width: 100%;
max-width: min
}
}
#error {
color: red;
}
#dnaa-container {
&>label[for="dnaa"],
&>input[type=checkbox] {
cursor: pointer;
}
}
\ No newline at end of file
......@@ -12,11 +12,13 @@
<img src="{{ $image }}" />
</div>
@if(Request::has('e'))
<p>
<font color="red">{{ __('Fehler: Falsche Eingabe!') }}</font>
</p>
<p id="error">{{ __('Fehler: Falsche Eingabe!') }}</p>
@endif
<p><input type="text" class="form-control" name="captcha" placeholder="@lang('captcha.3')" autofocus required></p>
<div id="dnaa-container">
<input type="checkbox" name="dnaa" id="dnaa" @if(Request::has("dnaa"))checked @endif>
<label for="dnaa">@lang('captcha.4')</label>
</div>
<p><button type="submit" class="btn btn-success" name="check">OK</button></p>
</form>
@endsection
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment