def checkSolution(self, request): """Process a solved CAPTCHA by sending it to the ReCaptcha server. The client's IP address is not sent to the ReCaptcha server; instead, a completely random IP is generated and sent instead. :type request: :api:`twisted.web.http.Request` :param request: A ``Request`` object, including POST arguments which should include two key/value pairs: one key being ``'captcha_challenge_field'``, and the other, ``'captcha_response_field'``. These POST arguments should be obtained from :meth:`render_GET`. :rtupe: :api:`twisted.internet.defer.Deferred` :returns: A deferred which will callback with a tuple in the following form: (:type:`bool`, :api:`twisted.web.server.Request`) If the CAPTCHA solution was valid, a tuple will contain:: (True, Request) Otherwise, it will contain:: (False, Request) """ challenge, response = self.extractClientSolution(request) clientIP = self.getClientIP(request) remoteIP = self.getRemoteIP() logging.debug("Captcha from %r. Parameters: %r" % (clientIP, request.args)) def checkResponse(solution, request): """Check the :class:`txrecaptcha.RecaptchaResponse`. :type solution: :class:`txrecaptcha.RecaptchaResponse`. :param solution: The client's CAPTCHA solution, after it has been submitted to the reCaptcha API server. """ # This valid CAPTCHA result from this function cannot be reliably # unittested, because it's callbacked to from the deferred # returned by ``txrecaptcha.submit``, the latter of which would # require networking (as well as automated CAPTCHA # breaking). Hence, the 'no cover' pragma. if solution.is_valid: # pragma: no cover logging.info("Valid CAPTCHA solution from %r." % clientIP) return (True, request) else: logging.info("Invalid CAPTCHA solution from %r: %r" % (clientIP, solution.error_code)) return (False, request) d = txrecaptcha.submit(challenge, response, self.secretKey, remoteIP).addCallback(checkResponse, request) return d
def test_submit_emptyResponseField(self): """An empty 'recaptcha_response_field' should return a deferred which callbacks with a RecaptchaResponse whose error_code is 'incorrect-captcha-sol'. """ def checkResponse(response): """Check that the response is a :class:`txcaptcha.RecaptchaResponse`. """ self.assertIsInstance(response, txrecaptcha.RecaptchaResponse) self.assertIs(response.is_valid, False) self.assertEqual(response.error_code, 'incorrect-captcha-sol') d = txrecaptcha.submit(self.challenge, '', self.key, self.ip) d.addCallback(checkResponse) return d
def test_submit_resultIsRecaptchaResponse(self): """Regardless of success or failure, the deferred returned from :func:`txrecaptcha.submit` should be a :class:`txcaptcha.RecaptchaResponse`. """ def checkResponse(response): """Check that the response is a :class:`txcaptcha.RecaptchaResponse`. """ self.assertIsInstance(response, txrecaptcha.RecaptchaResponse) self.assertIsInstance(response.is_valid, bool) self.assertIsInstance(response.error_code, basestring) d = txrecaptcha.submit(self.challenge, self.response, self.key, self.ip) d.addCallback(checkResponse) return d
def test_submit_resultIsRecaptchaResponse(self): """Regardless of success or failure, the deferred returned from :func:`txrecaptcha.submit` should be a :class:`txcaptcha.RecaptchaResponse`. """ if not os.environ.get("CI"): raise SkipTest(("This test requires network so it is only run " "on CI servers.")) def checkResponse(response): """Check that the response is a :class:`txcaptcha.RecaptchaResponse`. """ self.assertIsInstance(response, txrecaptcha.RecaptchaResponse) self.assertIsInstance(response.is_valid, bool) self.assertIsInstance(response.error_code, basestring) d = txrecaptcha.submit(self.challenge, self.response, self.key, self.ip) d.addCallback(checkResponse) return d
def test_submit_returnsDeferred(self): """:func:`txrecaptcha.submit` should return a deferred.""" response = txrecaptcha.submit(self.challenge, self.response, self.key, self.ip) self.assertIsInstance(response, defer.Deferred)