diff --git a/app/Http/Controllers/KeyController.php b/app/Http/Controllers/KeyController.php index f9f36a49c27a1ab5d2f7cbba69d31c54076bbd8b..417b95bf8df3d68cd38c076ed771524163e8f9e1 100644 --- a/app/Http/Controllers/KeyController.php +++ b/app/Http/Controllers/KeyController.php @@ -22,7 +22,7 @@ class KeyController extends Controller $redirUrl = $request->input('redirUrl', ""); $key = $request->input('key', ''); - if ($this->authorizeKey($key)) { + if (app('App\Models\Key')->getStatus()) { # Valid Key $host = $request->header("X_Forwarded_Host", ""); if (empty($host)) { @@ -45,32 +45,4 @@ class KeyController extends Controller $url = LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), action('KeyController@index', ['redirUrl' => $redirUrl])); return redirect($url); } - - private function authorizeKey($key) - { - $postdata = http_build_query(array( - 'dummy' => rand(), - )); - $opts = array('http' => array( - 'method' => 'POST', - 'header' => 'Content-type: application/x-www-form-urlencoded', - 'content' => $postdata, - ), - ); - - $context = stream_context_create($opts); - - try { - $link = "https://key.metager3.de/" . urlencode($key) . "/request-permission/api-access"; - $result = json_decode(file_get_contents($link, false, $context)); - if ($result->{'api-access'} == true) { - return true; - } else { - return false; - } - } catch (\ErrorException $e) { - return false; - } - - } } diff --git a/app/Http/Controllers/MetaGerSearch.php b/app/Http/Controllers/MetaGerSearch.php index dbc9c50dd124adf5603732e73754c7ddf1daac07..e1aaf1ba5001a500bc4f717b233dd2f3d96e925d 100644 --- a/app/Http/Controllers/MetaGerSearch.php +++ b/app/Http/Controllers/MetaGerSearch.php @@ -223,7 +223,7 @@ class MetaGerSearch extends Controller $metager->setAdgoalLoaded($adgoal["loaded"]); $metager->setAdgoalHash($adgoal["adgoalHash"]); - $metager->parseFormData($request); + $metager->parseFormData($request, false); # Nach Spezialsuchen überprüfen: $metager->checkSpecialSearches($request); $metager->restoreEngines($engines); diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index cb14ae7025a3077233dfb5cd09cd401242a20a52..e5eb7fc686bc6c83efc1d401d68080e329df9f41 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -63,5 +63,6 @@ class Kernel extends HttpKernel 'humanverification' => \App\Http\Middleware\HumanVerification::class, 'useragentmaster' => \App\Http\Middleware\UserAgentMaster::class, 'browserverification' => \App\Http\Middleware\BrowserVerification::class, + 'keyvalidation' => \App\Http\Middleware\KeyValidation::class, ]; } diff --git a/app/Http/Middleware/BrowserVerification.php b/app/Http/Middleware/BrowserVerification.php index f8ec4a32f4fd904c6d869a4605ce335ebcfe413e..0c1537db1edc33b30ae9e8a0af7c73e1ee8f5b21 100644 --- a/app/Http/Middleware/BrowserVerification.php +++ b/app/Http/Middleware/BrowserVerification.php @@ -18,7 +18,17 @@ class BrowserVerification */ public function handle($request, Closure $next) { - if ($request->filled("loadMore") && Cache::has($request->input("loadMore"))) { + + if(($request->input("out", "") === "api" || $request->input("out", "") === "atom10") && app('App\Models\Key')->getStatus()) { + header('Content-type: application/xml; charset=utf-8'); + } elseif(($request->input("out", "") === "api" || $request->input("out", "") === "atom10") && !app('App\Models\Key')->getStatus()) { + abort(403); + } else { + header('Content-type: text/html; charset=utf-8'); + } + header('X-Accel-Buffering: no'); + + if (($request->filled("loadMore") && Cache::has($request->input("loadMore"))) || app('App\Models\Key')->getStatus()) { return $next($request); } @@ -55,9 +65,6 @@ class BrowserVerification } } - header('Content-type: text/html; charset=utf-8'); - header('X-Accel-Buffering: no'); - $key = md5($request->ip() . microtime(true)); echo(view('layouts.resultpage.verificationHeader')->with('key', $key)->render()); diff --git a/app/Http/Middleware/HumanVerification.php b/app/Http/Middleware/HumanVerification.php index 805c86488a1e11b324ea55485f164d9eeb441e67..43997ee9ee90585bcce2a480bd8cfbefb35a077f 100644 --- a/app/Http/Middleware/HumanVerification.php +++ b/app/Http/Middleware/HumanVerification.php @@ -41,12 +41,12 @@ class HumanVerification unset($_SERVER["AGENT"]); /** - * If the user sends a Password or a key + * If the user sends a valid key or an appversion * We will not verificate the user. * If someone that uses a bot finds this out we * might have to change it at some point. */ - if ($request->filled('password') || $request->filled('key') || Cookie::get('key') !== null || $request->filled('appversion') || !env('BOT_PROTECTION', false)) { + if ($request->filled('appversion') || !env('BOT_PROTECTION', false) || app('App\Models\Key')->getStatus()) { $update = false; return $next($request); } diff --git a/app/MetaGer.php b/app/MetaGer.php index 11b2126bf549183e0e9f4ca87280248c8eb1fa36..e1a5084a7fddf4b05f39ab04c4bcf8bffc5c0134 100644 --- a/app/MetaGer.php +++ b/app/MetaGer.php @@ -206,33 +206,12 @@ class MetaGer ->with('browser', (new Agent())->browser()) ->with('fokus', $this->fokus); break; - case 'rich': - return view('resultpages.metager3rich') - ->with('results', $viewResults) - ->with('eingabe', $this->eingabe) - ->with('mobile', $this->mobile) - ->with('warnings', $this->warnings) - ->with('errors', $this->errors) - ->with('apiAuthorized', $this->apiAuthorized) - ->with('metager', $this) - ->with('browser', (new Agent())->browser()) - ->with('fokus', $this->fokus); - break; - case 'rss20': - return view('resultpages.metager3resultsrss20') - ->with('results', $viewResults) - ->with('eingabe', $this->eingabe) - ->with('apiAuthorized', $this->apiAuthorized) - ->with('metager', $this) - ->with('resultcount', sizeof($viewResults)) - ->with('fokus', $this->fokus); - break; + case 'api': - return response()->view('resultpages.metager3resultsatom10', ['results' => $viewResults, 'eingabe' => $this->eingabe, 'metager' => $this, 'resultcount' => sizeof($viewResults), 'key' => $this->apiKey, 'apiAuthorized' => $this->apiAuthorized])->header('Content-Type', 'application/xml'); + return view('resultpages.metager3resultsatom10',['eingabe' => $this->eingabe, 'resultcount' => sizeof($viewResults), 'key' => $this->apiKey, 'metager' => $this]); break; case 'atom10': - return response()->view('resultpages.metager3resultsatom10', ['results' => $viewResults, 'eingabe' => $this->eingabe, 'metager' => $this, 'resultcount' => sizeof($viewResults), 'key' => $this->apiKey, 'apiAuthorized' => true]) - ->header('Content-Type', 'application/xml'); + return view('resultpages.metager3resultsatom10',['eingabe' => $this->eingabe, 'resultcount' => sizeof($viewResults), 'key' => $this->apiKey, 'metager' => $this]); break; case 'result-count': # Wir geben die Ergebniszahl und die benötigte Zeit zurück: @@ -577,30 +556,7 @@ class MetaGer public function authorize($key) { - $postdata = http_build_query(array( - 'dummy' => rand(), - )); - $opts = array( - 'http' => array( - 'method' => 'POST', - 'header' => 'Content-type: application/x-www-form-urlencoded', - 'content' => $postdata, - ), - ); - - $context = stream_context_create($opts); - - try { - $link = "https://key.metager3.de/" . urlencode($key) . "/request-permission/api-access"; - $result = json_decode(file_get_contents($link, false, $context)); - if ($result->{'api-access'} == true) { - return true; - } else { - return false; - } - } catch (\ErrorException $e) { - return false; - } + return app('App\Models\Key')->requestPermission(); } /* @@ -1055,7 +1011,7 @@ class MetaGer * Ende Suchmaschinenerstellung und Ergebniserhalt */ - public function parseFormData(Request $request) + public function parseFormData(Request $request, $auth = true) { # Sichert, dass der request in UTF-8 formatiert ist if ($request->input('encoding', 'utf8') !== "utf8") { @@ -1191,7 +1147,7 @@ class MetaGer $this->apiKey = ""; } } - if ($this->apiKey) { + if ($this->apiKey && $auth) { $this->apiAuthorized = $this->authorize($this->apiKey); } @@ -1247,7 +1203,7 @@ class MetaGer $this->out = $request->input('out', "html"); # Standard output format html - if ($this->out !== "html" && $this->out !== "json" && $this->out !== "results" && $this->out !== "results-with-style" && $this->out !== "result-count" && $this->out !== "rss20" && $this->out !== "atom10" && $this->out !== "rich" && $this->out !== "api") { + if ($this->out !== "html" && $this->out !== "json" && $this->out !== "results" && $this->out !== "results-with-style" && $this->out !== "result-count" && $this->out !== "atom10" && $this->out !== "api") { $this->out = "html"; } # Wir schalten den Cache aus, wenn die Ergebniszahl überprüft werden soll diff --git a/app/Models/Key.php b/app/Models/Key.php new file mode 100644 index 0000000000000000000000000000000000000000..0af2ce89ce4ea0d4df9ddab028e5ea8269b2db58 --- /dev/null +++ b/app/Models/Key.php @@ -0,0 +1,73 @@ +<?php + +namespace App\Models; + +class Key{ + public $key; + public $status; # valid key = true, invalid key = false, unidentified key = null + + + public function __construct($key, $status = null){ + $this->key = $key; + $this->status = $status; + } + + # always returns true or false + public function getStatus() { + if($this->key !== '' && $this->status === null) { + $this->updateStatus(); + } + if($this->status === null || $this->status === false) { + return false; + } else { + return true; + } + } + + + public function updateStatus() { + + try { + $link = "https://key.metager3.de/" . urlencode($this->key) . "/request-permission/api-access"; + $result = json_decode(file_get_contents($link)); + if ($result->{'api-access'} == true) { + $this->status = true; + return true; + } else { + $this->status = false; + return false; + } + } catch (\ErrorException $e) { + return false; + } + } + + public function requestPermission() { + + $postdata = http_build_query(array( + 'dummy' => 0, + )); + $opts = array( + 'http' => array( + 'method' => 'POST', + 'header' => 'Content-type: application/x-www-form-urlencoded', + 'content' => $postdata, + ), + ); + + $context = stream_context_create($opts); + + try { + $link = "https://key.metager3.de/" . urlencode($this->key) . "/request-permission/api-access"; + $result = json_decode(file_get_contents($link, false, $context)); + if ($result->{'api-access'} == true) { + return true; + } else { + $this->status = false; + return false; + } + } catch (\ErrorException $e) { + return false; + } + } +} \ No newline at end of file diff --git a/app/Providers/KeyServiceProvider.php b/app/Providers/KeyServiceProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..d4922504a9abbed244d17b0f0571d2de6b701ee5 --- /dev/null +++ b/app/Providers/KeyServiceProvider.php @@ -0,0 +1,40 @@ +<?php + +namespace App\Providers; + +use Illuminate\Support\ServiceProvider; +use Request; +use Cookie; +use App\Models\Key; + +class KeyServiceProvider extends ServiceProvider +{ + /** + * Register services. + * + * @return void + */ + public function register() + { + $key = ""; + if(Cookie::has('key')) { + $key = Cookie::get('key'); + } + if(Request::filled('key')) { + $key = Request::input('key'); + } + $this->app->singleton(Key::class, function ($app) use ($key) { + return new Key($key); + }); + } + + /** + * Bootstrap services. + * + * @return void + */ + public function boot() + { + // + } +} diff --git a/config/app.php b/config/app.php index 47828b33d594d301f7af0c023709b3032f90cd4f..67d46683195056c5ead15a83f219c69c5b5f740f 100644 --- a/config/app.php +++ b/config/app.php @@ -179,6 +179,7 @@ return [ App\Providers\RouteServiceProvider::class, Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider::class, App\Providers\MetaGerProvider::class, + App\Providers\KeyServiceProvider::class, Jenssegers\Agent\AgentServiceProvider::class, Fideloper\Proxy\TrustedProxyServiceProvider::class, Mews\Captcha\CaptchaServiceProvider::class, diff --git a/resources/views/layouts/rich/ad.blade.php b/resources/views/layouts/rich/ad.blade.php deleted file mode 100644 index 7db614f4ca949f9af42477fa7df35b8481e86a46..0000000000000000000000000000000000000000 --- a/resources/views/layouts/rich/ad.blade.php +++ /dev/null @@ -1,17 +0,0 @@ -@if(isset($result) && !$apiAuthorized) -<article class="search-result ad card elevation-1"> - <div class="result-content"> - <h1 class="result-title">{{ $result->titel }}</h1> - <h2 class="result-display-link"><a href="{{ $result->link }}">{{ $result->anzeigeLink }}</a></h2> - <p class="result-description">{{ $result->descr }}</p> - <p class="result-source">Werbung von {!! $result->gefVon[0] !!}</p> - @if( isset($result->logo) ) - <img class="result-thumbnail" src="{{ $metager->getImageProxyLink($result->logo) }}" alt="" /> - @endif - </div> - <div class="result-action-area"> - <a class="result-action primary" href="{{ $result->link }}">Öffnen</a> - <a class="result-action primary" target="_blank" href="{{ $result->link }}">Neuer Tab</a> - </div> -</article> -@endif diff --git a/resources/views/layouts/rich/result.blade.php b/resources/views/layouts/rich/result.blade.php deleted file mode 100644 index c5b9d1f28f0f7924a83ec6f8497ed7813c3fc775..0000000000000000000000000000000000000000 --- a/resources/views/layouts/rich/result.blade.php +++ /dev/null @@ -1,16 +0,0 @@ -<article class="search-result card elevation-1"> - <div class="result-content"> - <h1 class="result-title">{{ $result->titel }}</h1> - <h2 class="result-display-link"><a href="{{ $result->link }}">{{ $result->anzeigeLink }}</a></h2> - <p class="result-description">{{ $result->descr }}</p> - <p class="result-source">gefunden von {!! $result->gefVon[0] !!}</p> - @if( isset($result->logo) ) - <img class="result-thumbnail" src="{{ $metager->getImageProxyLink($result->logo) }}" alt="" /> - @endif - </div> - <div class="result-action-area"> - <a class="result-action primary" href="{{ $result->link }}">Öffnen</a> - <a class="result-action primary" target="_blank" href="{{ $result->link }}">Neuer Tab</a> - <a class="result-action" target="_blank" href="{{ $result->proxyLink }}">Anonym Öffnen</a> - </div> -</article> diff --git a/resources/views/parts/searchbar.blade.php b/resources/views/parts/searchbar.blade.php index 7c071f02e308d9ce53f9cf6fffca134f06895ac8..f7abe514c3cca3a89e5f349b561607a659f6909e 100644 --- a/resources/views/parts/searchbar.blade.php +++ b/resources/views/parts/searchbar.blade.php @@ -3,8 +3,8 @@ <div class="searchbar {{$class ?? ''}}"> <div class="search-input-submit"> <div id="search-key"> - <a id="key-link" @if(isset($apiAuthorized) && $apiAuthorized)class="authorized" @else class="unauthorized"@endif href="{{ action('KeyController@index', ['redirUrl' => !empty($metager) ? $metager->generateSearchLink($metager->getFokus()) : url()->full() ]) }}" @if(!empty($metager) && $metager->isFramed())target="_top" @endif data-tooltip="{{ trans ('index.key.tooltip') }}" tabindex="0"> - <img @if(isset($apiAuthorized) && $apiAuthorized)src="/img/key-verified.svg" @else src="/img/key-icon.svg"@endif alt="" aria-hidden="true" id="searchbar-img-key"> + <a id="key-link" @if(app('App\Models\Key')->getStatus())class="authorized" @else class="unauthorized"@endif href="{{ action('KeyController@index', ['redirUrl' => !empty($metager) ? $metager->generateSearchLink($metager->getFokus()) : url()->full() ]) }}" @if(!empty($metager) && $metager->isFramed())target="_top" @endif data-tooltip="{{ trans ('index.key.tooltip') }}" tabindex="0"> + <img @if(app('App\Models\Key')->getStatus())src="/img/key-verified.svg" @else src="/img/key-icon.svg"@endif alt="" aria-hidden="true" id="searchbar-img-key"> </a> </div> <div class="search-input"> diff --git a/resources/views/resultpages/metager3resultsatom10.blade.php b/resources/views/resultpages/metager3resultsatom10.blade.php index 25df6e410513b4f15a9f0dc0cc42797533a71995..e373265aaab7715b7f890b08722f07ae680b0ffd 100644 --- a/resources/views/resultpages/metager3resultsatom10.blade.php +++ b/resources/views/resultpages/metager3resultsatom10.blade.php @@ -3,7 +3,7 @@ xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:mg="http://metager.de/opensearch/" xmlns:ad="http://a9.com/-/opensearch/extensions/advertisement/1.0/"> - <title>{!! htmlspecialchars($eingabe, ENT_XML1, 'UTF-8'); !!} - MetaGer</title> + <title>{{ htmlspecialchars($eingabe, ENT_XML1, 'UTF-8') }} - MetaGer</title> <link href="{{ url()->full() }}"/> <updated>{{ date('c') }}</updated> <opensearch:totalResults>{{ $resultcount }}</opensearch:totalResults> @@ -11,7 +11,6 @@ <link rel="next" href="{{ htmlspecialchars($metager->nextSearchLink() ,ENT_QUOTES) }}" type="application/atom+xml"/> <id>urn:uuid:1d634a8c-2764-424f-b082-6c96494b7240</id> @include('layouts.atom10ad', ['ad' => $metager->popAd()]) - @if($apiAuthorized) @foreach($metager->getResults() as $index => $result) @if(($index+1) % 5 === 0) @include('layouts.atom10ad', ['ad' => $metager->popAd()]) @@ -25,13 +24,4 @@ </content> </entry> @endforeach - @else - <ad:advertisement> - <ad:callOut type="TEXT">Fehler</ad:callOut> - <ad:title type="TEXT">Falscher Schlüssel angegeben</ad:title> - <ad:displayUrl type="TEXT">https://metager.de/meta/key</ad:displayUrl> - <ad:subTitle type="TEXT">Sie haben einen ungültigen Schlüssel angegeben</ad:subTitle> - <link href="https://metager.de/meta/key" /> - </ad:advertisement> - @endif </feed> diff --git a/resources/views/resultpages/metager3resultsrss20.blade.php b/resources/views/resultpages/metager3resultsrss20.blade.php deleted file mode 100644 index 28e2e0149b83cf2605e3f9598fa363f025f6e08c..0000000000000000000000000000000000000000 --- a/resources/views/resultpages/metager3resultsrss20.blade.php +++ /dev/null @@ -1,24 +0,0 @@ -<?xmlversion = "1.0"encoding = "UTF-8"?> - <rss version="2.0" - xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" - xmlns:mg="http://metager.de/opensearch/" - xmlns:atom="http://www.w3.org/2005/Atom"> - <channel> - <title>{!! htmlspecialchars($eingabe, ENT_XML1, 'UTF-8'); !!} - MetaGer</title> - <opensearch:totalResults>{{ $resultcount }}</opensearch:totalResults> - <opensearch:Query role="request" searchTerms="{{ htmlspecialchars($eingabe, ENT_QUOTES) }}"/> - <mg:nextSearchResults url="{{htmlspecialchars($metager->nextSearchLink() ,ENT_QUOTES)}}" /> - @if($apiAuthorized) - @foreach($metager->getResults() as $result) - <item> - <title>{!! htmlspecialchars($result->titel, ENT_XML1, 'UTF-8'); !!}</title> - <link>{!! htmlspecialchars($result->link, ENT_XML1, 'UTF-8'); !!}</link> - <mg:anzeigeLink>{!! htmlspecialchars($result->anzeigeLink, ENT_XML1, 'UTF-8'); !!}</mg:anzeigeLink> - <description> - {!! htmlspecialchars($result->longDescr, ENT_XML1, 'UTF-8'); !!} - </description> - </item> - @endforeach - @endif - </channel> - </rss> diff --git a/resources/views/resultpages/metager3rich.blade.php b/resources/views/resultpages/metager3rich.blade.php deleted file mode 100644 index 840e9772c9a7eb13d59aae2d9883467ca2bb8253..0000000000000000000000000000000000000000 --- a/resources/views/resultpages/metager3rich.blade.php +++ /dev/null @@ -1,59 +0,0 @@ -<!DOCTYPE html> -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta charset="UTF-8" /> - <meta http-equiv="X-UA-Compatible" content="IE=edge" /> - <title>{{ $eingabe }} - MetaGer</title> - <link @if(app('request')->input('theme', 'default')!=='default'&&app('request')->input('theme', 'default')!=='material')rel="alternate stylesheet" @else rel="stylesheet" @endif title="Material" href="{{ mix('/css/material-default.css') }}" /> - <link @if(app('request')->input('theme', 'default')!=='material-inverse')rel="alternate stylesheet" @else rel="stylesheet" @endif title="Material-Invers" href="{{ mix('/css/material-inverse.css') }}" /> - <link href="/font-awesome/css/font-awesome.min.css" rel="stylesheet" /> - <link href="/favicon.ico" rel="icon" type="image/x-icon" /> - <link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" /> - <meta content="width=device-width, initial-scale=1.0, user-scalable=no" name="viewport" /> - <meta HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE" /> - <link rel="search" type="application/opensearchdescription+xml" title="{!! trans('resultPage.opensearch') !!}" href="{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), action('StartpageController@loadPlugin', ['params' => base64_encode(serialize(Request::all()))])) }}"> - </head> - <body> - <header class="persistent-search"> - <form class="search-card card elevation-2"> - <a href="/" class="back"> - <img src="/img/Logo-square-inverted.svg" alt="MetaGer" title="MetaGer, die sichere Suchmaschine" /> - </a> - <input type="text" name="eingabe" placeholder="MetaGer-Suche" value="{{ $eingabe }}" class="query-input"/> - <button type="submit" class="search-button fa"></button> - @foreach( $metager->request->all() as $key => $value) - @if($key !== "eingabe" && $key !== "page" && $key !== "next") - <input type="hidden" name="{{ $key }}" value="{{ $value }}"/> - @endif - @endforeach - </form> - </header> - <details class="focus-card card elevation-1"> - <summary class="focus-cell"><div class="focus-cell-label"><span class="icon fa" aria-hidden="true"></span> <b>Web</b></div></summary> - </details> - <main class="results-container"> - @foreach($metager->getResults() as $result) - @if($result->number % 7 === 0 && !$apiAuthorized) - @include('layouts.rich.ad', ['result' => $metager->popAd()]) - @endif - @include('layouts.rich.result', ['result' => $result]) - @endforeach - </main> - @if($metager->getPage() === 1) - <nav class="pagenav-first"> - <a class="pagenav-button-next card elevation-1" href="{{ $metager->nextSearchLink() }}"><span class="card-button-text">Weitersuchen</span><span class="icon-right">►</span></a> - </nav> - @else - <nav class="pagenav-following"> - <div> - <a class="pagenav-button-first card-inline elevation-1" href="javascript:history.back()">◄</a> - </div> - <div class="pagenav-current"><span class="pagenav-current-annotation">Seite </span>{{ $metager->getPage() }}</div> - <a class="pagenav-button-next card-inline elevation-1" href="{{ $metager->nextSearchLink() }}"><span class="card-button-text">Weitersuchen</span><span class="icon-right">►</span></a> - </nav> - @endif - <footer class="footer-text"> - <a href="https://metager.de/impressum" target="_blank">Impressum</a> - </footer> - </body> -</html>