Changeset 15012
- Timestamp:
- 19 May 2018, 21:47:54 (7 years ago)
- Location:
- main/waeup.kofa/trunk/src/waeup/kofa/browser
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.kofa/trunk/src/waeup/kofa/browser/captcha.py
r12858 r15012 21 21 """ 22 22 import grok 23 import json 23 24 import urllib 24 25 import urllib2 … … 163 164 164 165 ## 165 ## ReCaptcha 166 ## 167 API_SSL_SERVER = "https://www.google.com/recaptcha/api" 168 VERIFY_SERVER = "https://www.google.com/recaptcha/api" 169 166 ## ReCaptcha (v2) 167 ## 170 168 class ReCaptcha(StaticCaptcha): 171 169 """ReCaptcha - strong captchas with images, sound, etc. 172 170 173 171 This is the Kofa implementation to support captchas as provided by 174 http://www.google.com/recaptcha .172 http://www.google.com/recaptcha (v2). 175 173 176 174 ReCaptcha is widely used and adopted in web applications. See the … … 220 218 This captcha is available at runtime as a global utility named 221 219 ``'ReCaptcha'``. 220 221 Shortcomings: 222 - no support for selecting theme 223 - no support for selecting box layout (normal, compact) 224 - no support for non-javascript users 225 - Google will get the data of our clients 226 - Google will track all activity of our clients 222 227 """ 223 228 224 229 grok.implements(ICaptcha) 225 230 226 #: name of solution field in HTTP request 227 sol_field = 'recaptcha_response_field' 228 #: name of challenge field in HTTP request 229 chal_field = 'recaptcha_challenge_field' 231 #: name of response token field in HTTP request 232 token_field = 'g-recaptcha-response' 230 233 231 234 # Do not use the following keys in productive environments! As … … 235 238 PRIVATE_KEY = "6Lc0y8oSAAAAAMHVbMrGWLLjw2pm8v2Uprwm9AbR" 236 239 240 VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify' 241 237 242 def verify(self, request): 238 243 """Grab challenge/solution from HTTP request and verify it. 239 244 240 245 Verification happens against recaptcha remote API servers. It 241 only happens, when really a solution was sent with the246 only happens, when a repsonse token was sent with the 242 247 request. 243 248 … … 246 251 """ 247 252 form = getattr(request, 'form', {}) 248 solution=form.get(self.sol_field, None) 249 challenge=form.get(self.chal_field, None) 250 if not challenge or not solution: 251 # Might be first-time display of the captcha: not a valid 252 # solution but no error code to prevent any error 253 # messages. Skip further verification. 254 return CaptchaResponse( 255 is_valid=False) 253 token = form.get(self.token_field, None) 254 if not token: 255 # on first-time display, we won't get a token 256 return CaptchaResponse(is_valid=False) 256 257 params = urllib.urlencode( 257 258 { 258 'privatekey': self.PRIVATE_KEY, 259 'secret': self.PRIVATE_KEY, 260 'response': token, 259 261 'remoteip': '127.0.0.1', 260 'challenge': challenge,261 'response': solution,262 262 }) 263 263 request = urllib2.Request( 264 url = "%s/verify" % VERIFY_SERVER,264 url = self.VERIFY_URL, 265 265 data = params, 266 266 headers = { … … 269 269 } 270 270 ) 271 resp = urllib2.urlopen(request) 272 ret_vals = resp.read().splitlines() 273 resp.close() 274 ret_code, err_code = ret_vals 275 276 if ret_code == "true": 271 conn = urllib2.urlopen(request) 272 ret_vals = json.loads(conn.read()) 273 conn.close() 274 if ret_vals.get('success', False) is True: 277 275 return CaptchaResponse(is_valid=True) 278 return CaptchaResponse(is_valid=False, error_code=ret_vals[1]) 276 return CaptchaResponse( 277 is_valid=False, error_code="%s" % ret_vals['error-codes']) 279 278 280 279 def display(self, error_code=None): 281 """Display c hallenge and input field for solution as HTML.280 """Display captcha widget snippet. 282 281 283 282 Returns the HTML code to be placed inside an existing ``<form>`` … … 297 296 html = ( 298 297 u'<script type="text/javascript" ' 299 u'src="%(ApiServer)s /challenge?k=%(PublicKey)s%(ErrorParam)s">'298 u'src="%(ApiServer)s" async defer>' 300 299 u'</script>' 301 u'' 302 u'<noscript>' 303 u'<iframe' 304 u' src="%(ApiServer)s/noscript?k=%(PublicKey)s%(ErrorParam)s"' 305 u' height="300" width="500" frameborder="0"></iframe><br />' 306 u'<textarea name="recaptcha_challenge_field"' 307 u' rows="3" cols="40"></textarea>' 308 u'<input type="hidden" name="recaptcha_response_field"' 309 u' value="manual_challenge" />' 310 u'</noscript>' % { 311 'ApiServer' : API_SSL_SERVER, 312 'PublicKey' : self.PUBLIC_KEY, 313 'ErrorParam' : error_param, 300 u'<div class="g-recaptcha" data-sitekey="%(SiteKey)s"></div>' % { 301 'ApiServer': "https://www.google.com/recaptcha/api.js", 302 'SiteKey': self.PUBLIC_KEY, 314 303 } 315 304 ) 316 305 return html 306 317 307 318 308 grok.global_utility(ReCaptcha, name=u'ReCaptcha') -
main/waeup.kofa/trunk/src/waeup/kofa/browser/tests/test_captcha.py
r7811 r15012 171 171 result = captcha.display() 172 172 self.assertMatches( 173 '<script type="text/javascript" src="..."></script>' 174 '<noscript>' 175 '<iframe src="..." height="300" width="500" ' 176 ' frameborder="0"></iframe><br />' 177 '<textarea name="recaptcha_challenge_field" rows="3" ' 178 ' cols="40"></textarea>' 179 '<input type="hidden" name="recaptcha_response_field" ' 180 ' value="manual_challenge" /></noscript>', 173 '<script type="text/javascript" ' 174 'src="..." async defer></script>' 175 '<div class="g-recaptcha" data-sitekey="..."></div>', 181 176 result) 182 177 return
Note: See TracChangeset for help on using the changeset viewer.