captcha.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import requests
  2. from recaptcha.client.captcha import displayhtml, submit as submit_recaptcha
  3. from django.utils.translation import ugettext_lazy as _
  4. from misago.conf import settings
  5. from misago.core import forms
  6. """
  7. Session flagging
  8. """
  9. def session_already_passed_test(session):
  10. return session.get('passed_captcha')
  11. def mark_session_as_passing(session):
  12. session['passed_captcha'] = True
  13. def reset_session(session):
  14. session.pop('passed_captcha', None)
  15. """
  16. Captcha tests
  17. """
  18. def recaptcha_test(request):
  19. r = requests.post('https://www.google.com/recaptcha/api/siteverify', data={
  20. 'secret': settings.recaptcha_secret_key,
  21. 'response': request.data.get('captcha'),
  22. 'remoteip': request.user_ip
  23. })
  24. if r.status_code == 200:
  25. response_json = r.json()
  26. if not response_json.get('success'):
  27. raise forms.ValidationError(_("Please try again."))
  28. else:
  29. raise forms.ValidationError(_("Failed to contact reCAPTCHA API."))
  30. def qacaptcha_test(request):
  31. answer = request.data.get('captcha', '').lower()
  32. for predefined_answer in settings.qa_answers.lower().splitlines():
  33. predefined_answer = predefined_answer.strip().lower()
  34. if answer == predefined_answer:
  35. break
  36. else:
  37. raise forms.ValidationError(_("Entered answer is incorrect."))
  38. def nocaptcha_test(request):
  39. return # no captcha means no validation
  40. CAPTCHA_TESTS = {
  41. 're': recaptcha_test,
  42. 'qa': qacaptcha_test,
  43. 'no': nocaptcha_test,
  44. }
  45. def test_request(request):
  46. if not session_already_passed_test(request.session):
  47. # run test and if it didn't raise validation error,
  48. # mark session as passing so we don't troll uses anymore
  49. CAPTCHA_TESTS[settings.captcha_type](request)
  50. mark_session_as_passing(request.session)