annotate antispam/utils.py @ 623:1555b2c3c7a0

For issue #22, add a UNIQUE contraint on the pending user table's username field.
author Brian Neal <bgneal@gmail.com>
date Wed, 31 Oct 2012 20:06:01 -0500
parents 8ddd6490cbc9
children 08d905e38a86
rev   line source
bgneal@214 1 """Antispam utility functions other apps can use."""
bgneal@215 2 import datetime
bgneal@215 3 import logging
bgneal@215 4 import textwrap
bgneal@215 5
bgneal@214 6 from django.core.cache import cache
bgneal@214 7
bgneal@214 8 from antispam import SPAM_PHRASE_KEY
bgneal@214 9 from antispam.models import SpamPhrase
bgneal@215 10 from core.functions import email_admins
bgneal@563 11 from bio.models import STA_SUSPENDED, STA_SPAMMER
bgneal@563 12 from comments.models import Comment
bgneal@563 13 from forums.tools import delete_user_posts
bgneal@214 14
bgneal@214 15
bgneal@214 16 def contains_spam(s):
bgneal@214 17 """This function returns True if the supplied string s contains any spam
bgneal@214 18 phrases and False otherwise.
bgneal@214 19 """
bgneal@214 20 phrases = _get_spam_phrases()
bgneal@215 21 s = s.lower()
bgneal@214 22 for spam in phrases:
bgneal@214 23 if spam in s:
bgneal@214 24 return True
bgneal@214 25
bgneal@214 26 return False
bgneal@214 27
bgneal@214 28
bgneal@215 29 def spam_check(request, content):
bgneal@215 30 """This function checks the supplied content for spam if the user from the
bgneal@215 31 supplied request is a stranger (new to the site). If spam is found, the
bgneal@215 32 function makes a log entry, emails the admins, suspends the user's account
bgneal@215 33 and returns True. If spam is not found, False is returned.
bgneal@215 34 It is assumed that request.user is an authenticated user and thus has a
bgneal@215 35 user profile.
bgneal@215 36 """
bgneal@215 37 user = request.user
bgneal@215 38 if user.get_profile().is_stranger() and contains_spam(content):
bgneal@215 39
bgneal@215 40 ip = request.META.get('REMOTE_ADDR', "unknown")
bgneal@215 41
bgneal@215 42 msg = textwrap.dedent("""\
bgneal@215 43 SPAM FILTER TRIPPED by %s
bgneal@215 44 PATH: %s
bgneal@215 45 IP: %s
bgneal@215 46 Message:
bgneal@215 47 %s
bgneal@215 48 """ % (user.username, request.path, ip, content))
bgneal@215 49
bgneal@215 50 logging.info(msg)
bgneal@215 51 email_admins("SPAM FILTER TRIPPED BY %s" % user.username, msg)
bgneal@215 52 suspend_user(user)
bgneal@215 53 return True
bgneal@215 54
bgneal@215 55 return False
bgneal@215 56
bgneal@215 57
bgneal@215 58 def suspend_user(user):
bgneal@215 59 """This function marks the user as suspended."""
bgneal@215 60 user.is_active = False
bgneal@215 61 user.save()
bgneal@215 62 profile = user.get_profile()
bgneal@215 63 profile.status = STA_SUSPENDED
bgneal@215 64 profile.status_date = datetime.datetime.now()
bgneal@562 65 profile.save(content_update=False)
bgneal@563 66 logging.info("User suspended: %s", user.username)
bgneal@563 67
bgneal@563 68
bgneal@563 69 def deactivate_spammer(user):
bgneal@563 70 """
bgneal@563 71 This function deactivate's the user, marks them as a spammer, then
bgneal@563 72 deletes the user's comments and forum posts. The spammer's profile is
bgneal@563 73 cleared so any spam links won't show up anymore.
bgneal@563 74
bgneal@563 75 """
bgneal@563 76 user.is_active = False
bgneal@563 77 user.save()
bgneal@563 78
bgneal@563 79 profile = user.get_profile()
bgneal@563 80 profile.status = STA_SPAMMER
bgneal@563 81 profile.status_date = datetime.datetime.now()
bgneal@563 82 profile.reset_text_fields()
bgneal@608 83 if profile.avatar:
bgneal@608 84 profile.avatar.delete(save=False)
bgneal@563 85 profile.save()
bgneal@563 86
bgneal@563 87 Comment.objects.filter(user=user).delete()
bgneal@563 88 delete_user_posts(user)
bgneal@563 89
bgneal@563 90 logging.info("User deactivated for spam: %s", user.username)
bgneal@316 91
bgneal@215 92
bgneal@214 93 def _get_spam_phrases():
bgneal@563 94 """
bgneal@563 95 This function returns the current list of spam phrase strings.
bgneal@214 96 The strings are cached to avoid hitting the database.
bgneal@563 97
bgneal@214 98 """
bgneal@214 99 phrases = cache.get(SPAM_PHRASE_KEY)
bgneal@214 100 if phrases:
bgneal@214 101 return phrases
bgneal@214 102
bgneal@214 103 phrases = SpamPhrase.objects.values_list('phrase', flat=True)
bgneal@214 104 cache.set(SPAM_PHRASE_KEY, phrases)
bgneal@214 105 return phrases