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
|