At this point, I am very close to done with this code! I made one big change at
[mediagoblin:mediagoblin.git] / mediagoblin / moderation / tools.py
1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors.  See AUTHORS.
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU Affero General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 from mediagoblin import mg_globals
18 from mediagoblin.db.models import User, Privilege, UserBan
19 from mediagoblin.db.base import Session
20 from mediagoblin.tools.mail import send_email
21 from mediagoblin.tools.response import redirect
22 from datetime import datetime
23 from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
24 import sys, traceback
25
26 def take_punitive_actions(request, form, report, user):
27     message_body =''
28
29     # The bulk of this action is running through all of the different
30     # punitive actions that a moderator could take.
31     if u'takeaway' in form.action_to_resolve.data:
32         for privilege_name in form.take_away_privileges.data:
33             take_away_privileges(user.username, privilege_name)
34             form.resolution_content.data += \
35                 u"\n{mod} took away {user}\'{privilege} privileges.".format(
36                     mod=request.user.username,
37                     user=user.username,
38                     privilege=privilege_name)
39
40     # If the moderator elects to ban the user, a new instance of user_ban
41     # will be created.
42     if u'userban' in form.action_to_resolve.data:
43         user_ban = ban_user(form.targeted_user.data,
44             expiration_date=form.user_banned_until.data,
45             reason=form.why_user_was_banned.data)
46         Session.add(user_ban)
47         form.resolution_content.data += \
48             u"\n{mod} banned user {user} {expiration_date}.".format(
49                 mod=request.user.username,
50                 user=user.username,
51                 expiration_date = (
52                 "until {date}".format(date=form.user_banned_until.data)
53                     if form.user_banned_until.data
54                     else "indefinitely"
55                     )
56             )
57
58     # If the moderator elects to send a warning message. An email will be
59     # sent to the email address given at sign up
60     if u'sendmessage' in form.action_to_resolve.data:
61         message_body = form.message_to_user.data
62         form.resolution_content.data += \
63             u"\n{mod} sent a warning email to the {user}.".format(
64                 mod=request.user.username,
65                 user=user.username)
66
67     if u'delete' in form.action_to_resolve.data and \
68         report.is_comment_report():
69             deleted_comment = report.comment
70             Session.delete(deleted_comment)
71             form.resolution_content.data += \
72                 u"\n{mod} deleted the comment.".format(
73                     mod=request.user.username)
74     elif u'delete' in form.action_to_resolve.data and \
75         report.is_media_entry_report():
76             deleted_media = report.media_entry
77             Session.delete(deleted_media)
78             form.resolution_content.data += \
79                 u"\n{mod} deleted the media entry.".format(
80                     mod=request.user.username)
81     report.archive(
82         resolver_id=request.user.id,
83         resolved=datetime.now(),
84         result=form.resolution_content.data)
85
86     Session.add(report)
87     Session.commit()
88     if message_body:
89         send_email(
90             mg_globals.app_config['email_sender_address'],
91             [user.email],
92             _('Warning from')+ '- {moderator} '.format(
93                 moderator=request.user.username),
94             message_body)
95
96     return redirect(
97         request,
98         'mediagoblin.moderation.users_detail',
99         user=user.username)
100
101
102 def take_away_privileges(user,*privileges):
103     """
104     Take away all of the privileges passed as arguments.
105
106         :param user             A Unicode object representing the target user's
107                                 User.username value.
108
109         :param privileges       A variable number of Unicode objects describing
110                                 the privileges being taken away.
111
112
113         :returns True           If ALL of the privileges were taken away
114                                 successfully.
115
116         :returns False          If ANY of the privileges were not taken away
117                                 successfully. This means the user did not have
118                                 (one of) the privilege(s) to begin with.
119     """
120     if len(privileges) == 1:
121         privilege = Privilege.query.filter(
122             Privilege.privilege_name==privileges[0]).first()
123         user = User.query.filter(
124             User.username==user).first()
125         if privilege in user.all_privileges:
126             user.all_privileges.remove(privilege)
127             return True
128         return False
129
130     elif len(privileges) > 1:
131         return (take_away_privileges(user, privileges[0]) and \
132             take_away_privileges(user, *privileges[1:]))
133
134 def give_privileges(user,*privileges):
135     """
136     Take away all of the privileges passed as arguments.
137
138         :param user             A Unicode object representing the target user's
139                                 User.username value.
140
141         :param privileges       A variable number of Unicode objects describing
142                                 the privileges being granted.
143
144
145         :returns True           If ALL of the privileges were granted successf-
146                                 -ully.
147
148         :returns False          If ANY of the privileges were not granted succ-
149                                 essfully. This means the user already had (one
150                                 of) the privilege(s) to begin with.
151     """
152     if len(privileges) == 1:
153         privilege = Privilege.query.filter(
154             Privilege.privilege_name==privileges[0]).first()
155         user = User.query.filter(
156             User.username==user).first()
157         if privilege not in user.all_privileges:
158             user.all_privileges.append(privilege)
159             return True
160         return False
161
162     elif len(privileges) > 1:
163         return (give_privileges(user, privileges[0]) and \
164             give_privileges(user, *privileges[1:]))
165
166 def ban_user(user_id, expiration_date=None, reason=None):
167     """
168     This function is used to ban a user. If the user is already banned, the
169     function returns False. If the user is not already banned, this function
170     bans the user using the arguments to build a new UserBan object.
171
172     :returns    False if the user is already banned and the ban is not updated
173     :returns    UserBan object if there is a new ban that was created.
174     """
175     user_ban =UserBan.query.filter(
176             UserBan.user_id==user_id)
177     if user_ban.count():
178         return False
179     new_user_ban = UserBan(
180         user_id=user_id,
181         expiration_date=expiration_date,
182         reason=reason)
183     return new_user_ban
184
185 def unban_user(user_id):
186     """
187     This function is used to unban a user. If the user is not currently banned,
188     nothing happens.
189
190     :returns    True if the operation was completed successfully and the user
191                 has been unbanned
192     :returns    False if the user was never banned.
193     """
194     user_ban = UserBan.query.filter(
195             UserBan.user_id==user_id)
196     if user_ban.count() == 0:
197         return False
198     user_ban.first().delete()
199     return True
200
201 def parse_report_panel_settings(form):
202     """
203     This function parses the url arguments to which are used to filter reports
204     in the reports panel view. More filters can be added to make a usuable
205     search function.
206
207     :returns    A dictionary of sqlalchemy-usable filters.
208     """
209     filters = {}
210
211     if form.validate():
212         filters['reported_user_id'] = form.reported_user.data
213         filters['reporter_id'] = form.reporter.data
214
215     filters = dict((k, v)
216         for k, v in filters.iteritems() if v)
217
218     return filters