Changeset 7303


Ignore:
Timestamp:
7 Dec 2011, 07:18:52 (13 years ago)
Author:
uli
Message:

Put ReCaptcha? into an ICaptcha implementation and see how much code we
can strip from the captcha test page. Not bad.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.sirp/trunk/src/waeup/sirp/browser/captcha.py

    r7300 r7303  
    237237##
    238238API_SSL_SERVER = "https://www.google.com/recaptcha/api"
    239 VERIFY_SERVER = "http://www.google.com"
     239VERIFY_SERVER = "https://www.google.com/recaptcha/api"
     240# Do not use the following keys in productive environments!
     241# As they are both made publicly available, they are not secure any more!
     242# Use them for testing and evaluating only!
    240243PUBLIC_KEY = "6Lc0y8oSAAAAAHwdojrqPtcKn7Rww5qGprb0rrSk"
    241244PRIVATE_KEY = "6Lc0y8oSAAAAAMHVbMrGWLLjw2pm8v2Uprwm9AbR"
    242245
    243 
    244 
    245 class RecaptchaResponse(object):
    246     def __init__(self, is_valid, error_code=None):
    247         self.is_valid = is_valid
    248         self.error_code = error_code
    249         return
    250 
    251 class CaptchaTestPage(SIRPPage):
    252     grok.name('captcha')
    253     grok.context(IUniversity)
    254     grok.require('waeup.Public')
    255     title = 'Captcha Test'
    256     label = title
    257 
    258     def update(self, recaptcha_challenge_field=None,
    259                recaptcha_response_field=None):
    260         self.error_code = None
    261         print "CHAL: ", recaptcha_challenge_field
    262         print "RESP: ", recaptcha_response_field
    263         print self.request.form.items()
    264         verify_result = 'NONE'
    265         if recaptcha_challenge_field and recaptcha_response_field:
    266             verify_result = self.verify(
    267                 recaptcha_challenge_field, recaptcha_response_field)
    268         print "VERIFY: ", verify_result
    269         if verify_result != 'NONE':
    270             print "  VALID: ", verify_result.is_valid
    271             print "  ERR: ", verify_result.error_code
    272             self.error_code = verify_result.error_code
    273         pass
    274 
    275     def verify(self, challenge, solution, private_key=PRIVATE_KEY,
    276                remote_ip='127.0.0.1'):
     246class ReCaptcha(StaticCaptcha):
     247
     248    grok.implements(ICaptcha)
     249
     250    #: name of solution field in HTTP request
     251    sol_field = 'recaptcha_response_field'
     252    #: name of challenge field in HTTP request
     253    chal_field = 'recaptcha_challenge_field'
     254
     255    def verify(self, request):
     256        form = getattr(request, 'form', {})
     257        solution=form.get(self.sol_field, None)
     258        challenge=form.get(self.chal_field, None)
    277259        if not challenge or not solution:
    278             return RecaptchaResponse(
    279                 is_valid=False, error_code='incorrect-captcha-sol')
     260            # maybe first display of the captcha: not a valid solution
     261            # but no error code to prevent any error messages
     262            return CaptchaResponse(
     263                is_valid=False)
    280264        params = urllib.urlencode(
    281265            {
    282                 'privatekey': private_key,
    283                 'remoteip': remote_ip,
     266                'privatekey': PRIVATE_KEY,
     267                'remoteip': '127.0.0.1',
    284268                'challenge': challenge,
    285269                'response': solution,
    286270                })
    287271        request = urllib2.Request(
    288             url = "%s/recaptcha/api/verify" % VERIFY_SERVER,
     272            url = "%s/verify" % VERIFY_SERVER,
    289273            data = params,
    290274            headers = {
     
    299283
    300284        if ret_code == "true":
    301             return RecaptchaResponse(is_valid=True)
    302         return RecaptchaResponse(is_valid=False, error_code=ret_vals[1])
     285            return CaptchaResponse(is_valid=True)
     286        return CaptchaResponse(is_valid=False, error_code=ret_vals[1])
     287
     288    def display(self, error_code=None):
     289        """Display challenge and input field for solution as HTML.
     290        """
     291        error_param = ''
     292        if error_code:
     293            error_param = '&error=%s' % error_code
     294
     295        html = (
     296            u'<script type="text/javascript" '
     297            u'src="%(ApiServer)s/challenge?k=%(PublicKey)s%(ErrorParam)s">'
     298            u'</script>'
     299            u''
     300            u'<noscript>'
     301            u'<iframe'
     302            u'    src="%(ApiServer)s/noscript?k=%(PublicKey)s%(ErrorParam)s"'
     303            u'    height="300" width="500" frameborder="0"></iframe><br />'
     304            u'<textarea name="recaptcha_challenge_field"'
     305            u'          rows="3" cols="40"></textarea>'
     306            u'<input type="hidden" name="recaptcha_response_field"'
     307            u'       value="manual_challenge" />'
     308            u'</noscript>' % {
     309                'ApiServer' : API_SSL_SERVER,
     310                'PublicKey' : PUBLIC_KEY,
     311                'ErrorParam' : error_param,
     312                }
     313            )
     314        return html
     315
     316grok.global_utility(ReCaptcha, name=u'ReCaptcha')
     317
     318
     319class CaptchaTestPage(SIRPPage):
     320    grok.name('captcha')
     321    grok.context(IUniversity)
     322    grok.require('waeup.Public')
     323    title = 'Captcha Test'
     324    label = title
     325
     326    def update(self, recaptcha_challenge_field=None,
     327               recaptcha_response_field=None):
     328        self.captcha = getUtility(ICaptcha, name='ReCaptcha')
     329        result = self.captcha.verify(self.request)
     330        self.captcha_error = result.error_code
     331        print "VERIFY: ", result.is_valid, result.error_code
     332        return
    303333
    304334    def render(self):
    305         error_param = ''
    306         if self.error_code:
    307             error_param = '&error=%s' % self.error_code
    308335        return """
    309336  <form method="POST" action="">
    310     <script type="text/javascript"
    311             src="%(ApiServer)s/challenge?k=%(PublicKey)s%(ErrorParam)s">
    312     </script>
    313 
    314     <noscript>
    315       <iframe src="%(ApiServer)s/noscript?k=%(PublicKey)s%(ErrorParam)s"
    316               height="300" width="500" frameborder="0"></iframe><br />
    317       <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
    318       <input type='hidden' name='recaptcha_response_field'
    319              value='manual_challenge' />
    320     </noscript>
     337    %s
    321338    <input type="submit" name="SUBMIT" />
    322339  </form>
    323 """ % {
    324         'ApiServer' : API_SSL_SERVER,
    325         'PublicKey' : PUBLIC_KEY,
    326         'ErrorParam' : error_param,
    327         }
     340  """ % (self.captcha.display(self.captcha_error),)
Note: See TracChangeset for help on using the changeset viewer.