Commit 994bae0f authored by Joseph Wilhelm's avatar Joseph Wilhelm
Browse files

This sure works a whole lot better.

 * Fixed the handling of error_messages. I could have sworn Django forms has error_messages and not just the fields
 * Storing a hash of the name/email/ip rather than the raw data, to prevent memcached key problems.
Note: The hashes for the keys really should be stored. Right now, each is generated up to 3 times. While sha256 may not be an entirely expensive operation, it’s not entirely inexpensive either.
parent e9ce3b88
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
import hashlib
import logging
from urllib import urlencode
import urllib2
@@ -20,13 +21,14 @@ class BotScoutForm(object):

    This mixin should precede forms.Form/ModelForm.
    """
    error_messages = {'botscout': _('This request was matched in the BotScout database')}

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        error_msg = getattr(self, 'BOTSCOUT_ERROR_MESSAGE',
                            _('This request was matched in the BotScout database'))
        super(BotScoutForm, self).__init__(*args, **kwargs)
        error_msg = getattr(self, 'BOTSCOUT_ERROR_MESSAGE', None)
        if error_msg is not None:
            self.error_messages['botscout'] = error_msg
        super(BotScoutForm, self).__init__(*args, **kwargs)

    def clean(self):
        data = super(BotScoutForm, self).clean()
@@ -42,14 +44,14 @@ class BotScoutForm(object):
        if using_ip:
            test_data['ip'] = self.request.META.get('REMOTE_ADDR', None)
        test_data = dict((x, y) for x, y in test_data.iteritems() if y is not None)
        cached_data = bot_cache.get_many(['botscout:%s:%s' % (x, y)
        cached_data = bot_cache.get_many(['botscout:%s:%s' % (x, hashlib.sha256(y).hexdigest())
                                          for x, y in test_data.iteritems()])
        if any(cached_data.values()):
            raise forms.ValidationError(self.error_messages['botscout'])
        untested = dict((x, y) for x, y in test_data.iteritems()
                        if 'botscout:%s:%s' % (x, y) not in cached_data)
                        if 'botscout:%s:%s' % (x, hashlib.sha256(y).hexdigest()) not in cached_data)
        if untested:
            test_url = '%s?multi%s' % (BOTSCOUT_API_URL, urlencode(untested))
            test_url = '%s?multi&%s' % (BOTSCOUT_API_URL, urlencode(untested))
            if BOTSCOUT_API_KEY is not None:
                test_url = '%s&key=%s' % (test_url, BOTSCOUT_API_KEY)
            try:
@@ -63,11 +65,11 @@ class BotScoutForm(object):
                     unused, name_hits) = response.split('|')
                    hit_data = {}
                    if 'ip' in untested:
                        hit_data['botscout:ip:%s' % untested['ip']] = int(ip_hits)
                        hit_data['botscout:ip:%s' % hashlib.sha256(untested['ip']).hexdigest()] = int(ip_hits)
                    if 'mail' in untested:
                        hit_data['botscout:mail:%s' % untested['mail']] = int(mail_hits)
                        hit_data['botscout:mail:%s' % hashlib.sha256(untested['mail']).hexdigest()] = int(mail_hits)
                    if 'name' in untested:
                        hit_data['botscout:name:%s' % untested['name']] = int(name_hits)
                        hit_data['botscout:name:%s' % hashlib.sha256(untested['name']).hexdigest()] = int(name_hits)
                    bot_cache.set_many(hit_data, BOTSCOUT_CACHE_TIMEOUT)
                    if any(hit_data.values()):
                        raise forms.ValidationError(self.error_messages['botscout'])