~widelands-dev/widelands-website/django_staticfiles

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env python -tt
# encoding: utf-8
from django.forms import *
import settings
import httplib, urllib

# Code was taken from http://smileychris.tactful.co.nz/static/uploads/recaptcha.py
# Thanks for implementing!

class RecaptchaWidget(Widget):
    def __init__(self, theme=None, tabindex=None):
        '''
        From http://recaptcha.net/apidocs/captcha/#look-n-feel:

        theme:      'red' | 'white' | 'blackglass'

            Defines which theme to use for reCAPTCHA.

        tabindex:   any integer

            Sets a tabindex for the reCAPTCHA text box. If other elements in
            the form use a tabindex, this should be set so that navigation is
            easier for the user.
        '''
        options = {}
        if theme:
            options['theme'] = theme
        if tabindex:
            options['tabindex'] = tabindex
        self.options = options
        super(RecaptchaWidget, self).__init__()

    def render(self, name, value, attrs=None):
        args = dict(public_key=settings.RECAPTCHA_PUBLIC_KEY)
        if self.options:
            args['options'] = '''<script type="text/javascript">
   var RecaptchaOptions = %r;
</script>
''' % self.options
        return '''%(options)s<script type="text/javascript"
   src="https://www.google.com/recaptcha/api/challenge?k=%(public_key)s">
</script>

<noscript>
   <iframe src="https://www.google.com/recaptcha/api/noscript?k=%(public_key)s"
       style="height: 300px; width: 500px; border: none;"></iframe><br />
   <textarea name="recaptcha_challenge_field" rows="3" cols="40">
   </textarea>
   <input type="hidden" name="recaptcha_response_field" 
       value="manual_challenge">
</noscript>''' % args

    def value_from_datadict(self, data, files, name):
        challenge = data.get('recaptcha_challenge_field')
        response = data.get('recaptcha_response_field')
        return (challenge, response)

    def id_for_label(self, id_):
        return None


class RecaptchaField(Field):
    widget = RecaptchaWidget

    def __init__(self, remote_ip, *args, **kwargs):
        self.remote_ip = remote_ip
        super(RecaptchaField, self).__init__(*args, **kwargs)
    
    def clean(self, value):
        value = super(RecaptchaField, self).clean(value)
        challenge, response = value
        if not challenge:
            raise ValidationError(u'An error occured with the CAPTCHA service. Please try again.')
        if not response:
            raise ValidationError(u'Please enter the CAPTCHA solution.')
        value = validate_recaptcha(self.remote_ip, challenge, response)
        if not value.get('result'):
            raise ValidationError(u'An incorrect CAPTCHA solution was entered.')
        return value


class RecaptchaFieldPlaceholder(Field):
    '''
    Placeholder field for use with RecaptchaBaseForm which gets replaced with
    RecaptchaField (which is passed the remote_ip) when RecaptchaBaseForm is
    initialised.
    '''
    def __init__(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs


class RecaptchaBaseForm(BaseForm):
    def __init__(self, remote_ip, *args, **kwargs):
        for key, field in self.base_fields.items():
            if isinstance(field, RecaptchaFieldPlaceholder):
                self.base_fields[key] = RecaptchaField(remote_ip, *field.args, **field.kwargs)
        super(RecaptchaBaseForm, self).__init__(*args, **kwargs)


class RecaptchaForm(RecaptchaBaseForm, Form):
    pass


def validate_recaptcha(remote_ip, challenge, response):
    # Request validation from recaptcha.net
    if challenge:
        params = urllib.urlencode(dict(privatekey=settings.RECAPTCHA_PRIVATE_KEY,
                                       remoteip=remote_ip,
                                       challenge=challenge,
                                       response=response))
        headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
        conn = httplib.HTTPConnection("api-verify.recaptcha.net")
        conn.request("POST", "/verify", params, headers)
        response = conn.getresponse()
        if response.status == 200:
            data = response.read()
        else:
            data = ''
        conn.close()
    # Validate based on response data
    result = data.startswith('true')
    error_code = ''
    if not result:
        bits = data.split('\n', 2)
        if len(bits) > 1:
            error_code = bits[1]
    # Return dictionary
    return dict(result=result,
                error_code=error_code)