diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php index e9390a7a..91c6450d 100644 --- a/app/Http/Controllers/AuthController.php +++ b/app/Http/Controllers/AuthController.php @@ -18,7 +18,7 @@ use App\Exceptions\PrettyPageException; class AuthController extends Controller { - public function handleLogin(Request $request) + public function handleLogin(Request $request, Captcha $captcha) { $this->validate($request, [ 'identification' => 'required', @@ -44,7 +44,7 @@ class AuthController extends Controller $loginFails = (int) Cache::get($loginFailsCacheKey, 0); if ($loginFails > 3) { - $this->validate($request, ['captcha' => ['required', new Captcha]]); + $this->validate($request, ['captcha' => ['required', $captcha]]); } if (! $user) { @@ -96,7 +96,7 @@ class AuthController extends Controller } } - public function handleRegister(Request $request) + public function handleRegister(Request $request, Captcha $captcha) { if (! option('user_can_register')) { return json(trans('auth.register.close'), 7); @@ -108,7 +108,7 @@ class AuthController extends Controller $data = $this->validate($request, array_merge([ 'email' => 'required|email|unique:users', 'password' => 'required|min:8|max:32', - 'captcha' => ['required', new Captcha], + 'captcha' => ['required', $captcha], ], $rule)); if (option('register_with_player_name')) { @@ -173,10 +173,10 @@ class AuthController extends Controller } } - public function handleForgot(Request $request) + public function handleForgot(Request $request, Captcha $captcha) { $this->validate($request, [ - 'captcha' => ['required', new Captcha], + 'captcha' => ['required', $captcha], ]); if (! config('mail.driver')) { diff --git a/app/Rules/Captcha.php b/app/Rules/Captcha.php index fc915a05..df673361 100644 --- a/app/Rules/Captcha.php +++ b/app/Rules/Captcha.php @@ -6,26 +6,31 @@ use Illuminate\Contracts\Validation\Rule; class Captcha implements Rule { + protected $client; + + public function __construct(\GuzzleHttp\Client $client) + { + $this->client = $client; + } + public function passes($attribute, $value) { - if (app()->environment('testing')) { - return true; - } - $secretkey = option('recaptcha_secretkey'); if ($secretkey) { - $client = new \GuzzleHttp\Client(); - $response = $client->post('https://www.recaptcha.net/recaptcha/api/siteverify', [ - 'form_params' => [ - 'secret' => $secretkey, - 'response' => $value, - ] - ]); - if ($response->getStatusCode() == 200) { - $body = json_decode((string) $response->getBody()); - return $body->success; + try { + $response = $this->client->post('https://www.recaptcha.net/recaptcha/api/siteverify', [ + 'form_params' => [ + 'secret' => $secretkey, + 'response' => $value, + ] + ]); + if ($response->getStatusCode() == 200) { + $body = json_decode((string) $response->getBody()); + return $body->success; + } + } catch (\GuzzleHttp\Exception\RequestException $e) { + return false; } - return false; } return captcha_check($value); diff --git a/tests/AuthControllerTest.php b/tests/AuthControllerTest.php index 49a37b64..404b46ef 100644 --- a/tests/AuthControllerTest.php +++ b/tests/AuthControllerTest.php @@ -17,6 +17,19 @@ class AuthControllerTest extends TestCase { use DatabaseTransactions; + protected function setUp(): void + { + parent::setUp(); + app()->instance(\App\Rules\Captcha::class, new class extends \App\Rules\Captcha { + public function __construct(\GuzzleHttp\Client $client = null) {} + + public function passes($attribute, $value) + { + return true; + } + }); + } + public function testLogin() { $this->get('/auth/login')->assertSee('Log in'); diff --git a/tests/RulesTest/CaptchaTest.php b/tests/RulesTest/CaptchaTest.php new file mode 100644 index 00000000..33272636 --- /dev/null +++ b/tests/RulesTest/CaptchaTest.php @@ -0,0 +1,41 @@ +instance('captcha', new class { + public function check() + { + return true; + } + }); + $rule = resolve(Captcha::class); + $this->assertTrue($rule->passes('captcha', 'any')); + $this->assertEquals(trans('validation.captcha'), $rule->message()); + } + + public function testRecaptcha() + { + option(['recaptcha_secretkey' => 'secret']); + $mock = new MockHandler([ + new Response(403), + new Response(200, [], json_encode(['success' => true])) + ]); + $handler = HandlerStack::create($mock); + $client = new Client(['handler' => $handler]); + + $rule = new Captcha($client); + $this->assertFalse($rule->passes('captcha', 'value')); + $this->assertTrue($rule->passes('captcha', 'value')); + $this->assertEquals(trans('validation.recaptcha'), $rule->message()); + } +}