| 18 | | class CommentForm(forms.Form): |
| 19 | | name = forms.CharField(label=_("Name"), max_length=50) |
| 20 | | email = forms.EmailField(label=_("Email address")) |
| 21 | | url = forms.URLField(label=_("URL"), required=False) |
| 22 | | comment = forms.CharField(label=_('Comment'), widget=forms.Textarea, |
| 23 | | max_length=COMMENT_MAX_LENGTH) |
| 24 | | honeypot = forms.CharField(required=False, |
| 25 | | label=_('If you enter anything in this field '\ |
| 26 | | 'your comment will be treated as spam')) |
| | 18 | class BaseCommentForm(forms.Form): |
| 37 | | super(CommentForm, self).__init__(data=data, initial=initial) |
| | 29 | super(BaseCommentForm, self).__init__(data=data, initial=initial) |
| | 30 | |
| | 31 | def generate_security_data(self): |
| | 32 | """Generate a dict of security data for "initial" data.""" |
| | 33 | timestamp = int(time.time()) |
| | 34 | security_dict = { |
| | 35 | 'content_type' : str(self.target_object._meta), |
| | 36 | 'object_pk' : str(self.target_object._get_pk_val()), |
| | 37 | 'timestamp' : str(timestamp), |
| | 38 | 'security_hash' : self.initial_security_hash(timestamp), |
| | 39 | } |
| | 40 | return security_dict |
| | 41 | |
| | 42 | def initial_security_hash(self, timestamp): |
| | 43 | """ |
| | 44 | Generate the initial security hash from self.content_object |
| | 45 | and a (unix) timestamp. |
| | 46 | """ |
| | 47 | |
| | 48 | initial_security_dict = { |
| | 49 | 'content_type' : str(self.target_object._meta), |
| | 50 | 'object_pk' : str(self.target_object._get_pk_val()), |
| | 51 | 'timestamp' : str(timestamp), |
| | 52 | } |
| | 53 | return self.generate_security_hash(**initial_security_dict) |
| | 54 | |
| | 55 | def generate_security_hash(self, content_type, object_pk, timestamp): |
| | 56 | """Generate a (SHA1) security hash from the provided info.""" |
| | 57 | info = (content_type, object_pk, timestamp, settings.SECRET_KEY) |
| | 58 | return sha_constructor("".join(info)).hexdigest() |
| | 59 | |
| | 60 | def security_errors(self): |
| | 61 | """Return just those errors associated with security""" |
| | 62 | errors = ErrorDict() |
| | 63 | for f in ["timestamp", "security_hash"]: |
| | 64 | if f in self.errors: |
| | 65 | errors[f] = self.errors[f] |
| | 66 | return errors |
| | 67 | |
| | 68 | def clean_security_hash(self): |
| | 69 | """Check the security hash.""" |
| | 70 | security_hash_dict = { |
| | 71 | 'content_type' : self.data.get("content_type", ""), |
| | 72 | 'object_pk' : self.data.get("object_pk", ""), |
| | 73 | 'timestamp' : self.data.get("timestamp", ""), |
| | 74 | } |
| | 75 | expected_hash = self.generate_security_hash(**security_hash_dict) |
| | 76 | actual_hash = self.cleaned_data["security_hash"] |
| | 77 | if expected_hash != actual_hash: |
| | 78 | raise forms.ValidationError("Security hash check failed.") |
| | 79 | return actual_hash |
| | 80 | |
| | 81 | def clean_timestamp(self): |
| | 82 | """Make sure the timestamp isn't too far (> 2 hours) in the past.""" |
| | 83 | ts = self.cleaned_data["timestamp"] |
| | 84 | if time.time() - ts > (2 * 60 * 60): |
| | 85 | raise forms.ValidationError("Timestamp check failed") |
| | 86 | return ts |
| | 87 | |
| | 88 | class MetaCommentForm(BaseCommentForm): |
| | 89 | name = forms.CharField(label=_("Name"), max_length=50) |
| | 90 | email = forms.EmailField(label=_("Email address")) |
| | 91 | url = forms.URLField(label=_("URL"), required=False) |
| | 92 | comment = forms.CharField(label=_('Comment'), widget=forms.Textarea, |
| | 93 | max_length=COMMENT_MAX_LENGTH) |
| 79 | | def security_errors(self): |
| 80 | | """Return just those errors associated with security""" |
| 81 | | errors = ErrorDict() |
| 82 | | for f in ["honeypot", "timestamp", "security_hash"]: |
| 83 | | if f in self.errors: |
| 84 | | errors[f] = self.errors[f] |
| 85 | | return errors |
| 86 | | |
| 87 | | def clean_honeypot(self): |
| 88 | | """Check that nothing's been entered into the honeypot.""" |
| 89 | | value = self.cleaned_data["honeypot"] |
| 90 | | if value: |
| 91 | | raise forms.ValidationError(self.fields["honeypot"].label) |
| 92 | | return value |
| 93 | | |
| 94 | | def clean_security_hash(self): |
| 95 | | """Check the security hash.""" |
| 96 | | security_hash_dict = { |
| 97 | | 'content_type' : self.data.get("content_type", ""), |
| 98 | | 'object_pk' : self.data.get("object_pk", ""), |
| 99 | | 'timestamp' : self.data.get("timestamp", ""), |
| 100 | | } |
| 101 | | expected_hash = self.generate_security_hash(**security_hash_dict) |
| 102 | | actual_hash = self.cleaned_data["security_hash"] |
| 103 | | if expected_hash != actual_hash: |
| 104 | | raise forms.ValidationError("Security hash check failed.") |
| 105 | | return actual_hash |
| 106 | | |
| 107 | | def clean_timestamp(self): |
| 108 | | """Make sure the timestamp isn't too far (> 2 hours) in the past.""" |
| 109 | | ts = self.cleaned_data["timestamp"] |
| 110 | | if time.time() - ts > (2 * 60 * 60): |
| 111 | | raise forms.ValidationError("Timestamp check failed") |
| 112 | | return ts |
| 113 | | |
| 147 | | initial_security_dict = { |
| 148 | | 'content_type' : str(self.target_object._meta), |
| 149 | | 'object_pk' : str(self.target_object._get_pk_val()), |
| 150 | | 'timestamp' : str(timestamp), |
| 151 | | } |
| 152 | | return self.generate_security_hash(**initial_security_dict) |
| | 157 | def security_errors(self): |
| | 158 | errors = super(CommentForm, self).security_errors() |
| | 159 | if 'honeypot' in self.errors: |
| | 160 | errors['honeypot'] = self.errors['honeypot'] |
| | 161 | return errors |
| | 162 | |
| | 163 | def clean_honeypot(self): |
| | 164 | """Check that nothing's been entered into the honeypot.""" |
| | 165 | value = self.cleaned_data["honeypot"] |
| | 166 | if value: |
| | 167 | raise forms.ValidationError(self.fields["honeypot"].label) |
| | 168 | return value |