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@780
|
14 from user_photos.s3 import delete_photos
|
bgneal@214
|
15
|
bgneal@214
|
16
|
bgneal@214
|
17 def contains_spam(s):
|
bgneal@214
|
18 """This function returns True if the supplied string s contains any spam
|
bgneal@214
|
19 phrases and False otherwise.
|
bgneal@214
|
20 """
|
bgneal@214
|
21 phrases = _get_spam_phrases()
|
bgneal@215
|
22 s = s.lower()
|
bgneal@214
|
23 for spam in phrases:
|
bgneal@214
|
24 if spam in s:
|
bgneal@214
|
25 return True
|
bgneal@214
|
26
|
bgneal@214
|
27 return False
|
bgneal@214
|
28
|
bgneal@214
|
29
|
bgneal@215
|
30 def spam_check(request, content):
|
bgneal@215
|
31 """This function checks the supplied content for spam if the user from the
|
bgneal@215
|
32 supplied request is a stranger (new to the site). If spam is found, the
|
bgneal@215
|
33 function makes a log entry, emails the admins, suspends the user's account
|
bgneal@215
|
34 and returns True. If spam is not found, False is returned.
|
bgneal@215
|
35 It is assumed that request.user is an authenticated user and thus has a
|
bgneal@215
|
36 user profile.
|
bgneal@215
|
37 """
|
bgneal@215
|
38 user = request.user
|
bgneal@789
|
39 if user.profile.is_stranger() and contains_spam(content):
|
bgneal@215
|
40
|
bgneal@215
|
41 ip = request.META.get('REMOTE_ADDR', "unknown")
|
bgneal@215
|
42
|
bgneal@215
|
43 msg = textwrap.dedent("""\
|
bgneal@215
|
44 SPAM FILTER TRIPPED by %s
|
bgneal@215
|
45 PATH: %s
|
bgneal@215
|
46 IP: %s
|
bgneal@215
|
47 Message:
|
bgneal@215
|
48 %s
|
bgneal@215
|
49 """ % (user.username, request.path, ip, content))
|
bgneal@215
|
50
|
bgneal@215
|
51 logging.info(msg)
|
bgneal@215
|
52 email_admins("SPAM FILTER TRIPPED BY %s" % user.username, msg)
|
bgneal@215
|
53 suspend_user(user)
|
bgneal@215
|
54 return True
|
bgneal@215
|
55
|
bgneal@215
|
56 return False
|
bgneal@215
|
57
|
bgneal@215
|
58
|
bgneal@215
|
59 def suspend_user(user):
|
bgneal@215
|
60 """This function marks the user as suspended."""
|
bgneal@215
|
61 user.is_active = False
|
bgneal@215
|
62 user.save()
|
bgneal@789
|
63 profile = user.profile
|
bgneal@215
|
64 profile.status = STA_SUSPENDED
|
bgneal@215
|
65 profile.status_date = datetime.datetime.now()
|
bgneal@562
|
66 profile.save(content_update=False)
|
bgneal@563
|
67 logging.info("User suspended: %s", user.username)
|
bgneal@563
|
68
|
bgneal@563
|
69
|
bgneal@563
|
70 def deactivate_spammer(user):
|
bgneal@563
|
71 """
|
bgneal@563
|
72 This function deactivate's the user, marks them as a spammer, then
|
bgneal@563
|
73 deletes the user's comments and forum posts. The spammer's profile is
|
bgneal@563
|
74 cleared so any spam links won't show up anymore.
|
bgneal@563
|
75
|
bgneal@563
|
76 """
|
bgneal@563
|
77 user.is_active = False
|
bgneal@563
|
78 user.save()
|
bgneal@563
|
79
|
bgneal@789
|
80 profile = user.profile
|
bgneal@563
|
81 profile.status = STA_SPAMMER
|
bgneal@563
|
82 profile.status_date = datetime.datetime.now()
|
bgneal@625
|
83 profile.reset()
|
bgneal@608
|
84 if profile.avatar:
|
bgneal@608
|
85 profile.avatar.delete(save=False)
|
bgneal@563
|
86 profile.save()
|
bgneal@563
|
87
|
bgneal@625
|
88 # delete comments & forum posts
|
bgneal@563
|
89 Comment.objects.filter(user=user).delete()
|
bgneal@563
|
90 delete_user_posts(user)
|
bgneal@563
|
91
|
bgneal@625
|
92 # delete elsewhere links
|
bgneal@625
|
93 user.social_network_profiles.all().delete()
|
bgneal@625
|
94 user.instant_messenger_profiles.all().delete()
|
bgneal@625
|
95 user.website_profiles.all().delete()
|
bgneal@625
|
96
|
bgneal@625
|
97 # delete shouts
|
bgneal@625
|
98 user.shout_set.all().delete()
|
bgneal@625
|
99
|
bgneal@780
|
100 # delete any uploaded photos
|
bgneal@780
|
101 photos = user.uploaded_photos.all()
|
bgneal@780
|
102 if len(photos):
|
bgneal@780
|
103 delete_photos(photos)
|
bgneal@780
|
104 photos.delete()
|
bgneal@780
|
105
|
bgneal@563
|
106 logging.info("User deactivated for spam: %s", user.username)
|
bgneal@316
|
107
|
bgneal@215
|
108
|
bgneal@214
|
109 def _get_spam_phrases():
|
bgneal@563
|
110 """
|
bgneal@563
|
111 This function returns the current list of spam phrase strings.
|
bgneal@214
|
112 The strings are cached to avoid hitting the database.
|
bgneal@563
|
113
|
bgneal@214
|
114 """
|
bgneal@214
|
115 phrases = cache.get(SPAM_PHRASE_KEY)
|
bgneal@214
|
116 if phrases:
|
bgneal@214
|
117 return phrases
|
bgneal@214
|
118
|
bgneal@214
|
119 phrases = SpamPhrase.objects.values_list('phrase', flat=True)
|
bgneal@214
|
120 cache.set(SPAM_PHRASE_KEY, phrases)
|
bgneal@214
|
121 return phrases
|