Merge branch 'stable'
[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 import six
18
19 from mediagoblin import mg_globals
20 from mediagoblin.db.models import User, Privilege, UserBan, LocalUser
21 from mediagoblin.db.base import Session
22 from mediagoblin.tools.mail import send_email
23 from mediagoblin.tools.response import redirect
24 from datetime import datetime
25 from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
26
27
28 def take_punitive_actions(request, form, report, user):
29 message_body = ''
30
31 # The bulk of this action is running through all of the different
32 # punitive actions that a moderator could take.
33 if u'takeaway' in form.action_to_resolve.data:
34 for privilege_name in form.take_away_privileges.data:
35 take_away_privileges(user.username, privilege_name)
36 form.resolution_content.data += \
37 _(u"\n{mod} took away {user}\'s {privilege} privileges.").format(
38 mod=request.user.username,
39 user=user.username,
40 privilege=privilege_name)
41
42 # If the moderator elects to ban the user, a new instance of user_ban
43 # will be created.
44 if u'userban' in form.action_to_resolve.data:
45 user_ban = ban_user(form.targeted_user.data,
46 expiration_date=form.user_banned_until.data,
47 reason=form.why_user_was_banned.data)
48 Session.add(user_ban)
49 form.resolution_content.data += \
50 _(u"\n{mod} banned user {user} {expiration_date}.").format(
51 mod=request.user.username,
52 user=user.username,
53 expiration_date = (
54 _("until {date}").format(date=form.user_banned_until.data)
55 if form.user_banned_until.data
56 else _("indefinitely")
57 )
58 )
59
60 # If the moderator elects to send a warning message. An email will be
61 # sent to the email address given at sign up
62 if u'sendmessage' in form.action_to_resolve.data:
63 message_body = form.message_to_user.data
64 form.resolution_content.data += \
65 _(u"\n{mod} sent a warning email to the {user}.").format(
66 mod=request.user.username,
67 user=user.username)
68
69 if u'delete' in form.action_to_resolve.data and \
70 report.is_comment_report():
71 deleted_comment = report.obj()
72 Session.delete(deleted_comment)
73 form.resolution_content.data += \
74 _(u"\n{mod} deleted the comment.").format(
75 mod=request.user.username)
76 elif u'delete' in form.action_to_resolve.data and \
77 report.is_media_entry_report():
78 deleted_media = report.obj()
79 deleted_media.delete()
80 form.resolution_content.data += \
81 _(u"\n{mod} deleted the media entry.").format(
82 mod=request.user.username)
83 report.archive(
84 resolver_id=request.user.id,
85 resolved=datetime.now(),
86 result=form.resolution_content.data)
87
88 Session.add(report)
89 Session.commit()
90 if message_body:
91 send_email(
92 mg_globals.app_config['email_sender_address'],
93 [user.email],
94 _('Warning from')+ '- {moderator} '.format(
95 moderator=request.user.username),
96 message_body)
97
98 return redirect(
99 request,
100 'mediagoblin.moderation.users_detail',
101 user=user.username)
102
103
104 def take_away_privileges(user,*privileges):
105 """
106 Take away all of the privileges passed as arguments.
107
108 :param user A Unicode object representing the target user's
109 User.username value.
110
111 :param privileges A variable number of Unicode objects describing
112 the privileges being taken away.
113
114
115 :returns True If ALL of the privileges were taken away
116 successfully.
117
118 :returns False If ANY of the privileges were not taken away
119 successfully. This means the user did not have
120 (one of) the privilege(s) to begin with.
121 """
122 if len(privileges) == 1:
123 privilege = Privilege.query.filter(
124 Privilege.privilege_name==privileges[0]).first()
125 user = LocalUser.query.filter(
126 LocalUser.username==user
127 ).first()
128 if privilege in user.all_privileges:
129 user.all_privileges.remove(privilege)
130 return True
131 return False
132
133 elif len(privileges) > 1:
134 return (take_away_privileges(user, privileges[0]) and \
135 take_away_privileges(user, *privileges[1:]))
136
137 def give_privileges(user,*privileges):
138 """
139 Take away all of the privileges passed as arguments.
140
141 :param user A Unicode object representing the target user's
142 User.username value.
143
144 :param privileges A variable number of Unicode objects describing
145 the privileges being granted.
146
147
148 :returns True If ALL of the privileges were granted successf-
149 -ully.
150
151 :returns False If ANY of the privileges were not granted succ-
152 essfully. This means the user already had (one
153 of) the privilege(s) to begin with.
154 """
155 if len(privileges) == 1:
156 privilege = Privilege.query.filter(
157 Privilege.privilege_name==privileges[0]).first()
158 user = LocalUser.query.filter(
159 LocalUser.username==user
160 ).first()
161 if privilege not in user.all_privileges:
162 user.all_privileges.append(privilege)
163 return True
164 return False
165
166 elif len(privileges) > 1:
167 return (give_privileges(user, privileges[0]) and \
168 give_privileges(user, *privileges[1:]))
169
170 def ban_user(user_id, expiration_date=None, reason=None):
171 """
172 This function is used to ban a user. If the user is already banned, the
173 function returns False. If the user is not already banned, this function
174 bans the user using the arguments to build a new UserBan object.
175
176 :returns False if the user is already banned and the ban is not updated
177 :returns UserBan object if there is a new ban that was created.
178 """
179 user_ban =UserBan.query.filter(
180 UserBan.user_id==user_id)
181 if user_ban.count():
182 return False
183 new_user_ban = UserBan(
184 user_id=user_id,
185 expiration_date=expiration_date,
186 reason=reason)
187 return new_user_ban
188
189 def unban_user(user_id):
190 """
191 This function is used to unban a user. If the user is not currently banned,
192 nothing happens.
193
194 :returns True if the operation was completed successfully and the user
195 has been unbanned
196 :returns False if the user was never banned.
197 """
198 user_ban = UserBan.query.filter(
199 UserBan.user_id==user_id)
200 if user_ban.count() == 0:
201 return False
202 user_ban.first().delete()
203 return True
204
205 def parse_report_panel_settings(form):
206 """
207 This function parses the url arguments to which are used to filter reports
208 in the reports panel view. More filters can be added to make a usuable
209 search function.
210
211 :returns A dictionary of sqlalchemy-usable filters.
212 """
213 filters = {}
214
215 if form.validate():
216 filters['reported_user_id'] = form.reported_user.data
217 filters['reporter_id'] = form.reporter.data
218
219 filters = dict((k, v)
220 for k, v in six.iteritems(filters) if v)
221
222 return filters