From 92b23fd6aa22a3948b18d00969e436b66efc5e18 Mon Sep 17 00:00:00 2001 From: Italo Date: Fri, 29 May 2020 01:38:09 -0400 Subject: [PATCH 1/3] Minor typo fixes. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7429a05..f7623c7 100644 --- a/README.md +++ b/README.md @@ -250,7 +250,7 @@ Here is the full array of [reCAPTCHA credentials](#set-up) to use depending on t ## Testing with Captchavel -When unit testing your application, this package [automatically fakes reCAPTCHA responses](#fake-responses) by setting. +When unit testing your application, this package [automatically fakes reCAPTCHA responses](#fake-responses). > When mocking requests, there is no need to add any reCAPTCHA token or secrets in your tests. @@ -280,7 +280,7 @@ $this->post('login', [ Alternatively, `fakeScore()` method that will fake any score you set. -> Fake responses don't come with action, hostnames or APK package names. +> Fake responses don't come with actions, hostnames or APK package names. ### Events From 768ff1e9f7a25b794f69edd43ec91bf1a42d9853 Mon Sep 17 00:00:00 2001 From: DarkGhostHunter Date: Tue, 2 Jun 2020 16:13:33 -0400 Subject: [PATCH 2/3] Fixed threshold not working as intended. Fixed macros absent. I literally fucked up that by just forgetting to add them to the code and call it a day. Please don't bully me, it was like 2:00 AM and I was so sleepy when I remembered to finish this package for my project that I could literally sleep in the chair. Next time I'll try to sleep properly. --- src/CaptchavelServiceProvider.php | 4 ++ src/Http/ReCaptchaResponse.php | 2 +- src/RequestMacro.php | 28 +++++++++ tests/Http/Middleware/ScoreMiddlewareTest.php | 58 ++++++++++++++++--- 4 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 src/RequestMacro.php diff --git a/src/CaptchavelServiceProvider.php b/src/CaptchavelServiceProvider.php index 17e673c..6f3bb60 100644 --- a/src/CaptchavelServiceProvider.php +++ b/src/CaptchavelServiceProvider.php @@ -2,6 +2,7 @@ namespace DarkGhostHunter\Captchavel; +use Illuminate\Http\Request; use Illuminate\Routing\Router; use Illuminate\Support\ServiceProvider; use Illuminate\Contracts\Config\Repository; @@ -43,5 +44,8 @@ public function boot(Router $router, Repository $config) $router->aliasMiddleware('recaptcha.v2', VerifyReCaptchaV2::class); $router->aliasMiddleware('recaptcha.v3', VerifyReCaptchaV3::class); + + Request::macro('isRobot', [RequestMacro::class, 'isRobot']); + Request::macro('isHuman', [RequestMacro::class, 'isHuman']); } } diff --git a/src/Http/ReCaptchaResponse.php b/src/Http/ReCaptchaResponse.php index 6661154..51a1f66 100644 --- a/src/Http/ReCaptchaResponse.php +++ b/src/Http/ReCaptchaResponse.php @@ -52,7 +52,7 @@ public function isHuman() throw new LogicException('This is not a reCAPTCHA v3 response, or the score is absent.'); } - return $this->threshold >= $this->score; + return $this->score >= $this->threshold; } /** diff --git a/src/RequestMacro.php b/src/RequestMacro.php new file mode 100644 index 0000000..3bdb0e2 --- /dev/null +++ b/src/RequestMacro.php @@ -0,0 +1,28 @@ +isHuman(); + } + + /** + * Check if the reCAPTCHA response is below threshold score. + * + * @return bool + */ + public static function isRobot() + { + return ! static::isHuman(); + } +} \ No newline at end of file diff --git a/tests/Http/Middleware/ScoreMiddlewareTest.php b/tests/Http/Middleware/ScoreMiddlewareTest.php index 738fe2b..061cdfd 100644 --- a/tests/Http/Middleware/ScoreMiddlewareTest.php +++ b/tests/Http/Middleware/ScoreMiddlewareTest.php @@ -5,9 +5,12 @@ use Tests\RegistersPackage; use Illuminate\Http\Request; use Orchestra\Testbench\TestCase; +use Illuminate\Http\Client\Factory; +use Illuminate\Http\Client\Response; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Event; use DarkGhostHunter\Captchavel\Captchavel; +use GuzzleHttp\Psr7\Response as GuzzleResponse; use DarkGhostHunter\Captchavel\Http\ReCaptchaResponse; use DarkGhostHunter\Captchavel\Events\ReCaptchaResponseReceived; @@ -28,8 +31,6 @@ protected function setUp() : void public function test_bypass_if_not_enabled() { - config(['captchavel.enable' => false]); - $event = Event::fake(); $this->mock(Captchavel::class)->shouldNotReceive('useCredentials', 'retrieve'); @@ -50,11 +51,11 @@ public function test_validates_if_real() ->andReturnSelf(); $mock->shouldReceive('retrieve') ->with('token', '127.0.0.1') - ->andReturn(new ReCaptchaResponse([ - 'success' => true, - 'score' => 0.5, - 'foo' => 'bar' - ])); + ->andReturn(new ReCaptchaResponse([ + 'success' => true, + 'score' => 0.5, + 'foo' => 'bar' + ])); $this->post('v3/default', [ Captchavel::INPUT => 'token' @@ -484,4 +485,47 @@ public function test_exception_if_action_not_equal() Captchavel::INPUT => 'token' ])->assertJsonValidationErrors('action'); } + + public function test_checks_for_human_score() + { + config(['captchavel.credentials.v3.secret' => 'secret']); + config(['captchavel.fake' => false]); + + $mock = $this->mock(Factory::class); + + $mock->shouldReceive('asForm')->withNoArgs()->times(4)->andReturnSelf(); + $mock->shouldReceive('withOptions')->with(['version' => 2.0])->times(4)->andReturnSelf(); + $mock->shouldReceive('post') + ->with(Captchavel::RECAPTCHA_ENDPOINT, [ + 'secret' => 'secret', + 'response' => 'token', + 'remoteip' => '127.0.0.1', + ]) + ->times(4) + ->andReturn(new Response(new GuzzleResponse(200, ['Content-type' => 'application/json'], json_encode([ + 'success' => true, + 'score' => 0.5, + ])))); + + Route::post('human_human', function (Request $request) { + return $request->isHuman() ? 'true' : 'false'; + })->middleware('recaptcha.v3:0.7'); + + Route::post('human_robot', function (Request $request) { + return $request->isRobot() ? 'true' : 'false'; + })->middleware('recaptcha.v3:0.7'); + + Route::post('robot_human', function (Request $request) { + return $request->isHuman() ? 'true' : 'false'; + })->middleware('recaptcha.v3:0.3'); + + Route::post('robot_robot', function (Request $request) { + return $request->isRobot() ? 'true' : 'false'; + })->middleware('recaptcha.v3:0.3'); + + $this->post('human_human', [Captchavel::INPUT => 'token'])->assertSee('false'); + $this->post('human_robot', [Captchavel::INPUT => 'token'])->assertSee('true'); + $this->post('robot_human', [Captchavel::INPUT => 'token'])->assertSee('true'); + $this->post('robot_robot', [Captchavel::INPUT => 'token'])->assertSee('false'); + } } From 99286ed99337ed416d90254c55387fb9c7a29a72 Mon Sep 17 00:00:00 2001 From: DarkGhostHunter Date: Tue, 2 Jun 2020 17:28:48 -0400 Subject: [PATCH 3/3] Fioxed test for bypassing when not enabled. --- tests/Http/Middleware/ScoreMiddlewareTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Http/Middleware/ScoreMiddlewareTest.php b/tests/Http/Middleware/ScoreMiddlewareTest.php index 061cdfd..4021732 100644 --- a/tests/Http/Middleware/ScoreMiddlewareTest.php +++ b/tests/Http/Middleware/ScoreMiddlewareTest.php @@ -31,6 +31,8 @@ protected function setUp() : void public function test_bypass_if_not_enabled() { + config(['captchavel.enable' => false]); + $event = Event::fake(); $this->mock(Captchavel::class)->shouldNotReceive('useCredentials', 'retrieve');