This was a big commit! I included lots of documentation below, but generally I

did a few things. I wrote many many many new tests, either in old test files or
in the three new test files I made. I also did some code-keeping work, deleting
trailing whitespace and deleting vestigial code. Lastly, I fixed the parts of
the code which I realized were broken thru the process of running tests.

===============================================================================
 Deleted trailing whitespace:
===============================================================================
--\  mediagoblin/decorators.py
--\  mediagoblin/auth/tools.py
--\  mediagoblin/db/migrations.py
--\  mediagoblin/db/models.py
--\  mediagoblin/gmg_commands/users.py
--\  mediagoblin/moderation/forms.py
--\  mediagoblin/moderation/tools.py
--\  mediagoblin/moderation/views.py
--\  mediagoblin/templates/mediagoblin/moderation/media_panel.html
--\  mediagoblin/templates/mediagoblin/moderation/report.html
--\  mediagoblin/templates/mediagoblin/moderation/report_panel.html
--\  mediagoblin/templates/mediagoblin/moderation/user.html
--\  mediagoblin/templates/mediagoblin/moderation/user_panel.html
--\  mediagoblin/templates/mediagoblin/user_pages/report.html
--\  mediagoblin/templates/mediagoblin/utils/report.html
--\  mediagoblin/user_pages/lib.py
--\  mediagoblin/user_pages/views.py
===============================================================================
 Deleted Vestigial Code
===============================================================================
--\  mediagoblin/db/util.py
--\  mediagoblin/tests/test_notifications.py
===============================================================================
 Modified the Code:
===============================================================================
--\  mediagoblin/moderation/tools.py
--| Encapsulated the code around giving/taking away privileges into two
  | funtions.

--\  mediagoblin/moderation/views.py
--| Imported and used the give/take away privilege functions
--| Replaced 'require_admin_or_moderator_login' with
  |'user_has_privilege(u"admin")' for adding/taking away privileges, only
  | admins are allowed to do this.

--\  mediagoblin/templates/mediagoblin/banned.html
--| Added relevant translation tags
--| Added ability to display indefinite banning

--\  mediagoblin/templates/mediagoblin/user_pages/media.html
--| Made sure the add comments button was only visible for users with the
  | `commenter` privilege

--\  mediagoblin/tests/test_submission.py
--| Paroneayea fixed a DetachedInstanceError I was having with the our_user
  | function

--\  mediagoblin/tests/tools.py
--| Added a fixture_add_comment_report function for testing.

--\  mediagoblin/tools/response.py
--| Fixed a minor error where a necessary return statement was missing
--| Fit the code within 80 columns

--\  mediagoblin/user_pages/views.py
--| Added a necessary decorator to ensure that only users with the 'commenter'
  | privilege can post comments
===============================================================================
 Wrote new tests for an old test file:
===============================================================================
--\  mediagoblin/tests/test_auth.py
--| Added a new test to make sure privilege granting on registration happens
  | correctly

--\  mediagoblin/tests/test_modelmethods.py*
--| Added a test to ensure the User method has_privilege works properly
===============================================================================
 Wrote entirely new files full of tests:
===============================================================================
--\  mediagoblin/tests/test_moderation.py
--\  mediagoblin/tests/test_privileges.py
--\  mediagoblin/tests/test_reporting.py
===============================================================================
===============================================================================
NOTE: Any files I've marked with a * in this commit report, were actually subm-
itted in my last commit. I made that committ to fix an error I was having, so
they weren't properly documented in that report.
===============================================================================
===============================================================================
This commit is contained in:
tilly-Q 2013-08-29 13:47:50 -04:00
parent e46fb71c1d
commit dfd66b789c
28 changed files with 793 additions and 157 deletions

View File

@ -68,24 +68,6 @@ def check_collection_slug_used(creator_id, slug, ignore_c_id):
does_exist = Session.query(Collection.id).filter(filt).first() is not None
return does_exist
def user_privileges_to_dictionary(user_id):
"""
This function accepts a users id and returns a dictionary of True or False
values for each privilege the user does or does not have. This allows for
easier referencing of a user's privileges inside templates.
"""
privilege_dictionary = {}
user = User.query.get(user_id)
users_privileges = [p_item.privilege_name for p_item in user.all_privileges]
#TODO update this to account for plugins that may add foundations
for privilege in FOUNDATIONS[Privilege]:
privilege_name = privilege['privilege_name']
if privilege_name in users_privileges:
privilege_dictionary[privilege_name]=True
else:
privilege_dictionary[privilege_name]=False
return privilege_dictionary
if __name__ == '__main__':
from mediagoblin.db.open import setup_connection_and_db_from_config

View File

@ -31,14 +31,12 @@ def take_punitive_actions(request, form, report, user):
# punitive actions that a moderator could take.
if u'takeaway' in form.action_to_resolve.data:
for privilege_name in form.take_away_privileges.data:
privilege = Privilege.query.filter(
Privilege.privilege_name==privilege_name).one()
take_away_privileges(user.username, privilege_name)
form.resolution_content.data += \
u"<br>%s took away %s\'s %s privileges" % (
u"<br>%s took away %s\'s %s privileges." % (
request.user.username,
user.username,
privilege.privilege_name)
user.all_privileges.remove(privilege)
privilege_name)
# If the moderator elects to ban the user, a new instance of user_ban
# will be created.
@ -86,14 +84,14 @@ def take_punitive_actions(request, form, report, user):
deleted_comment = report.comment
Session.delete(deleted_comment)
form.resolution_content.data += \
u"<br>%s deleted the comment" % (
u"<br>%s deleted the comment." % (
request.user.username)
elif u'delete' in form.action_to_resolve.data and \
report.is_media_entry_report():
deleted_media = report.media_entry
Session.delete(deleted_media)
form.resolution_content.data += \
u"<br>%s deleted the media entry" % (
u"<br>%s deleted the media entry." % (
request.user.username)
# If the moderator didn't delete the content we then attach the
@ -133,3 +131,34 @@ def take_punitive_actions(request, form, report, user):
request,
'mediagoblin.moderation.reports_detail',
report_id=report.id)
def take_away_privileges(user,*privileges):
if len(privileges) == 1:
privilege = Privilege.query.filter(
Privilege.privilege_name==privileges[0]).first()
user = User.query.filter(
User.username==user).first()
if privilege in user.all_privileges:
user.all_privileges.remove(privilege)
return True
return False
elif len(privileges) > 1:
return (take_away_privileges(user, privileges[0]) and \
take_away_privileges(user, *privileges[1:]))
def give_privileges(user,*privileges):
if len(privileges) == 1:
privilege = Privilege.query.filter(
Privilege.privilege_name==privileges[0]).first()
user = User.query.filter(
User.username==user).first()
if privilege not in user.all_privileges:
user.all_privileges.append(privilege)
return True
return False
elif len(privileges) > 1:
return (give_privileges(user, privileges[0]) and \
give_privileges(user, *privileges[1:]))

View File

@ -19,12 +19,12 @@ from werkzeug.exceptions import Forbidden
from mediagoblin.db.models import (MediaEntry, User, MediaComment, \
CommentReport, ReportBase, Privilege, \
UserBan, ArchivedReport)
from mediagoblin.db.util import user_privileges_to_dictionary
from mediagoblin.decorators import (require_admin_or_moderator_login, \
active_user_from_url)
active_user_from_url, user_has_privilege)
from mediagoblin.tools.response import render_to_response, redirect
from mediagoblin.moderation import forms as moderation_forms
from mediagoblin.moderation.tools import take_punitive_actions
from mediagoblin.moderation.tools import (take_punitive_actions, \
take_away_privileges, give_privileges)
from datetime import datetime
@require_admin_or_moderator_login
@ -134,7 +134,7 @@ def moderation_reports_detail(request):
{'report':report,
'form':form})
@require_admin_or_moderator_login
@user_has_privilege(u'admin')
@active_user_from_url
def give_or_take_away_privilege(request, url_user):
'''
@ -144,11 +144,12 @@ def give_or_take_away_privilege(request, url_user):
if request.method == "POST" and form.validate():
privilege = Privilege.query.filter(
Privilege.privilege_name==form.privilege_name.data).one()
if privilege in url_user.all_privileges:
url_user.all_privileges.remove(privilege)
else:
url_user.all_privileges.append(privilege)
if not take_away_privileges(
url_user.username, form.privilege_name.data):
give_privileges(url_user.username, form.privilege_name.data)
url_user.save()
return redirect(
request,
'mediagoblin.moderation.users_detail',

View File

@ -17,12 +17,19 @@
#}
{% extends "mediagoblin/base.html" %}
{% block title %}You are Banned.{% endblock %}
{% block title %}{% trans %}You are Banned.{% endtrans %}{% endblock %}
{% block mediagoblin_content %}
<img class="right_align" src="{{ request.staticdirect('/images/404.png') }}"
alt="{% trans %}Image of goblin stressing out{% endtrans %}" />
<h1>You have been banned until {{ expiration_date }}</h1>
<h1>{% trans %}You have been banned{% endtrans %}
{% if expiration_date %}
{% trans %}until{% endtrans %} {{ expiration_date }}
{% else %}
{% trans %}indefinitely{% endtrans %}
{% endif %}
</h2>
<p>{{ reason|safe }}</p>
<div class="clear"></div>
{% endblock %}

View File

@ -86,7 +86,7 @@
{% autoescape False %}
<p>{{ media.description_html }}</p>
{% endautoescape %}
{% if comments %}
{% if comments and request.user.has_privilege('commenter') %}
{% if app_config['allow_comments'] %}
<a
{% if not request.user %}

View File

@ -330,6 +330,13 @@ def test_authentication_views(test_app):
'next' : '/u/chris/'})
assert urlparse.urlsplit(response.location)[2] == '/u/chris/'
def test_basic_privileges_granted_on_registration(test_app):
user = User.query.filter(User.username==u'angrygirl').first()
assert User.has_privilege(u'commenter')
assert User.has_privilege(u'uploader')
assert User.has_privilege(u'reporter')
assert not User.has_privilege(u'active')
@pytest.fixture()
def authentication_disabled_app(request):

View File

@ -0,0 +1,194 @@
# GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
from mediagoblin.tests.tools import (fixture_add_user,
fixture_add_comment_report, fixture_add_comment)
from mediagoblin.db.models import User, CommentReport, MediaComment, UserBan
from mediagoblin.moderation.tools import take_away_privileges, give_privileges
from mediagoblin.tools import template, mail
from webtest import AppError
class TestModerationViews:
@pytest.fixture(autouse=True)
def _setup(self, test_app):
self.test_app = test_app
fixture_add_user(u'admin',
privileges=[u'admin',u'active'])
fixture_add_user(u'moderator',
privileges=[u'moderator',u'active'])
fixture_add_user(u'regular',
privileges=[u'active',u'commenter'])
self.query_for_users()
def login(self, username):
self.test_app.post(
'/auth/login/', {
'username': username,
'password': 'toast'})
self.query_for_users()
def logout(self):
self.test_app.get('/auth/logout/')
self.query_for_users()
def query_for_users(self):
self.admin_user = User.query.filter(User.username==u'admin').first()
self.mod_user = User.query.filter(User.username==u'moderator').first()
self.user = User.query.filter(User.username==u'regular').first()
def do_post(self, data, *context_keys, **kwargs):
url = kwargs.pop('url', '/submit/')
do_follow = kwargs.pop('do_follow', False)
template.clear_test_template_context()
response = self.test_app.post(url, data, **kwargs)
if do_follow:
response.follow()
context_data = template.TEMPLATE_TEST_CONTEXT
for key in context_keys:
context_data = context_data[key]
return response, context_data
def testGiveOrTakeAwayPrivileges(self):
self.login(u'admin')
# First, test an admin taking away a privilege from a user
#----------------------------------------------------------------------
response, context = self.do_post({'privilege_name':u'commenter'},
url='/mod/users/{0}/privilege/'.format(self.user.username))
assert response.status == '302 FOUND'
self.query_for_users()
assert not self.user.has_privilege(u'commenter')
# Then, test an admin giving a privilege to a user
#----------------------------------------------------------------------
response, context = self.do_post({'privilege_name':u'commenter'},
url='/mod/users/{0}/privilege/'.format(self.user.username))
assert response.status == '302 FOUND'
self.query_for_users()
assert self.user.has_privilege(u'commenter')
# Then, test a mod trying to take away a privilege from a user
# they are not allowed to do this, so this will raise an error
#----------------------------------------------------------------------
self.logout()
self.login(u'moderator')
with pytest.raises(AppError) as excinfo:
response, context = self.do_post({'privilege_name':u'commenter'},
url='/mod/users/{0}/privilege/'.format(self.user.username))
assert 'Bad response: 403 FORBIDDEN' in str(excinfo)
self.query_for_users()
assert self.user.has_privilege(u'commenter')
def testReportResolution(self):
self.login(u'moderator')
# First, test a moderators taking away a user's privilege in response
# to a reported comment
#----------------------------------------------------------------------
fixture_add_comment_report(reported_user=self.user)
comment_report = CommentReport.query.filter(
CommentReport.reported_user==self.user).first()
response = self.test_app.get('/mod/reports/{0}/'.format(
comment_report.id))
assert response.status == '200 OK'
self.query_for_users()
comment_report = CommentReport.query.filter(
CommentReport.reported_user==self.user).first()
response, context = self.do_post({'action_to_resolve':[u'takeaway'],
'take_away_privileges':[u'commenter'],
'targeted_user':self.user.id},
url='/mod/reports/{0}/'.format(comment_report.id))
assert response.status == '302 FOUND'
fixture_add_comment_report(reported_user=self.user)
comment_report = CommentReport.query.filter(
CommentReport.reported_user==self.user).first()
assert not self.user.has_privilege(u'commenter')
# Then, test a moderator sending an email to a user in response to a
# reported comment
#----------------------------------------------------------------------
self.query_for_users()
response, context = self.do_post({'action_to_resolve':[u'sendmessage'],
'message_to_user':'This is your last warning, regular....',
'targeted_user':self.user.id},
url='/mod/reports/{0}/'.format(comment_report.id))
assert response.status == '302 FOUND'
assert mail.EMAIL_TEST_MBOX_INBOX == [{'to': [u'regular@example.com'],
'message': 'Content-Type: text/plain; charset="utf-8"\n\
MIME-Version: 1.0\nContent-Transfer-Encoding: base64\nSubject: Warning from- \
moderator \nFrom: notice@mediagoblin.example.org\nTo: regular@example.com\n\n\
VGhpcyBpcyB5b3VyIGxhc3Qgd2FybmluZywgcmVndWxhci4uLi4=\n',
'from': 'notice@mediagoblin.example.org'}]
# Then test a moderator banning a user AND a moderator deleting the
# offending comment. This also serves as a test for taking multiple
# actions to resolve a report
#----------------------------------------------------------------------
self.query_for_users()
fixture_add_comment(author=self.user.id,
comment=u'Comment will be removed')
test_comment = MediaComment.query.filter(
MediaComment.author==self.user.id).first()
fixture_add_comment_report(comment=test_comment,
reported_user=self.user)
comment_report = CommentReport.query.filter(
CommentReport.reported_user==self.user).first()
response, context = self.do_post(
{'action_to_resolve':[u'userban', u'delete'],
'targeted_user':self.user.id},
url='/mod/reports/{0}/'.format(comment_report.id))
assert response.status == '302 FOUND'
self.query_for_users()
test_user_ban = UserBan.query.filter(
UserBan.user_id == self.user.id).first()
assert test_user_ban is not None
test_comment = MediaComment.query.filter(
MediaComment.author==self.user.id).first()
assert test_comment is None
# Then, test what happens when a moderator attempts to punish an admin
# from a reported comment on an admin.
#----------------------------------------------------------------------
fixture_add_comment_report(reported_user=self.admin_user)
comment_report = CommentReport.query.filter(
CommentReport.reported_user==self.admin_user).first()
response, context = self.do_post({'action_to_resolve':[u'takeaway'],
'take_away_privileges':[u'active'],
'targeted_user':self.admin_user.id},
url='/mod/reports/{0}/'.format(comment_report.id))
self.query_for_users()
assert response.status == '200 OK'
assert self.admin_user.has_privilege(u'active')
def testAllModerationViews(self):
self.login(u'moderator')
self.test_app.get('/mod/reports/')
self.test_app.get('/mod/users/')
self.test_app.get('/mod/media/')

View File

@ -127,7 +127,6 @@ otherperson@example.com\n\nSGkgb3RoZXJwZXJzb24sCmNocmlzIGNvbW1lbnRlZCBvbiB5b3VyI
else:
assert mail.EMAIL_TEST_MBOX_INBOX == []
mail.EMAIL_TEST_MBOX_INBOX = []
# Save the ids temporarily because of DetachedInstanceError
notification_id = notification.id

View File

@ -0,0 +1,206 @@
# GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
from datetime import datetime, timedelta
from webtest import AppError
from mediagoblin.tests.tools import fixture_add_user, fixture_media_entry
from mediagoblin.db.models import User, Privilege, UserBan
from mediagoblin.db.base import Session
from mediagoblin.tools import template
from .resources import GOOD_JPG
class TestPrivilegeFunctionality:
@pytest.fixture(autouse=True)
def _setup(self, test_app):
self.test_app = test_app
fixture_add_user(u'alex',
privileges=[u'admin',u'active'])
fixture_add_user(u'raven',
privileges=[u'moderator',u'active',u'reporter'])
fixture_add_user(u'natalie',
privileges=[u'active'])
self.query_for_users()
def login(self, username):
self.test_app.post(
'/auth/login/', {
'username': username,
'password': 'toast'})
self.query_for_users()
def logout(self):
self.test_app.get('/auth/logout/')
self.query_for_users()
def do_post(self, data, *context_keys, **kwargs):
url = kwargs.pop('url', '/submit/')
do_follow = kwargs.pop('do_follow', False)
template.clear_test_template_context()
response = self.test_app.post(url, data, **kwargs)
if do_follow:
response.follow()
context_data = template.TEMPLATE_TEST_CONTEXT
for key in context_keys:
context_data = context_data[key]
return response, context_data
def query_for_users(self):
self.admin_user = User.query.filter(User.username==u'alex').first()
self.mod_user = User.query.filter(User.username==u'raven').first()
self.user = User.query.filter(User.username==u'natalie').first()
def testUserBanned(self):
self.login(u'natalie')
uid = self.user.id
# First, test what happens when a user is banned indefinitely
#----------------------------------------------------------------------
user_ban = UserBan(user_id=uid,
reason=u'Testing whether user is banned',
expiration_date=None)
user_ban.save()
response = self.test_app.get('/')
assert response.status == "200 OK"
assert "You are Banned" in response.body
# Then test what happens when that ban has an expiration date which
# hasn't happened yet
#----------------------------------------------------------------------
user_ban = UserBan.query.get(uid)
user_ban.delete()
user_ban = UserBan(user_id=uid,
reason=u'Testing whether user is banned',
expiration_date= datetime.now() + timedelta(days=20))
user_ban.save()
response = self.test_app.get('/')
assert response.status == "200 OK"
assert "You are Banned" in response.body
# Then test what happens when that ban has an expiration date which
# has already happened
#----------------------------------------------------------------------
user_ban = UserBan.query.get(uid)
user_ban.delete()
exp_date = datetime.now() - timedelta(days=20)
user_ban = UserBan(user_id=uid,
reason=u'Testing whether user is banned',
expiration_date= exp_date)
user_ban.save()
response = self.test_app.get('/')
assert response.status == "302 FOUND"
assert not "You are Banned" in response.body
def testVariousPrivileges(self):
# The various actions that require privileges (ex. reporting,
# commenting, moderating...) are tested in other tests. This method
# will be used to ensure that those actions are impossible for someone
# without the proper privileges.
# For other tests that show what happens when a user has the proper
# privileges, check out:
# tests/test_moderation.py moderator
# tests/test_notifications.py commenter
# tests/test_reporting.py reporter
# tests/test_submission.py uploader
#----------------------------------------------------------------------
self.login(u'natalie')
# First test the get and post requests of submission/uploading
#----------------------------------------------------------------------
with pytest.raises(AppError) as excinfo:
response = self.test_app.get('/submit/')
assert 'Bad response: 403 FORBIDDEN' in str(excinfo)
with pytest.raises(AppError) as excinfo:
response = self.do_post({'upload_files':[('file',GOOD_JPG)],
'title':u'Normal Upload 1'},
url='/submit/')
assert 'Bad response: 403 FORBIDDEN' in str(excinfo)
# Test that a user cannot comment without the commenter privilege
#----------------------------------------------------------------------
self.query_for_users()
media_entry = fixture_media_entry(uploader=self.admin_user.id,
state=u'processed')
media_entry_id = media_entry.id
media_uri_id = '/u/{0}/m/{1}/'.format(self.admin_user.username,
media_entry.id)
media_uri_slug = '/u/{0}/m/{1}/'.format(self.admin_user.username,
media_entry.slug)
response = self.test_app.get(media_uri_slug)
assert not "Add a comment" in response.body
self.query_for_users()
with pytest.raises(AppError) as excinfo:
response = self.test_app.post(
media_uri_id + 'comment/add/',
{'comment_content': u'Test comment #42'})
assert 'Bad response: 403 FORBIDDEN' in str(excinfo)
# Test that a user cannot report without the reporter privilege
#----------------------------------------------------------------------
with pytest.raises(AppError) as excinfo:
response = self.test_app.get(media_uri_slug+"report/")
assert 'Bad response: 403 FORBIDDEN' in str(excinfo)
with pytest.raises(AppError) as excinfo:
response = self.do_post(
{'report_reason':u'Testing Reports #1',
'reporter_id':u'3'},
url=(media_uri_slug+"report/"))
assert 'Bad response: 403 FORBIDDEN' in str(excinfo)
# Test that a user cannot access the moderation pages w/o moderator
# or admin privileges
#----------------------------------------------------------------------
with pytest.raises(AppError) as excinfo:
response = self.test_app.get("/mod/users/")
assert 'Bad response: 403 FORBIDDEN' in str(excinfo)
with pytest.raises(AppError) as excinfo:
response = self.test_app.get("/mod/reports/")
assert 'Bad response: 403 FORBIDDEN' in str(excinfo)
with pytest.raises(AppError) as excinfo:
response = self.test_app.get("/mod/media/")
assert 'Bad response: 403 FORBIDDEN' in str(excinfo)
with pytest.raises(AppError) as excinfo:
response = self.test_app.get("/mod/users/1/")
assert 'Bad response: 403 FORBIDDEN' in str(excinfo)
with pytest.raises(AppError) as excinfo:
response = self.test_app.get("/mod/reports/1/")
assert 'Bad response: 403 FORBIDDEN' in str(excinfo)
self.query_for_users()
with pytest.raises(AppError) as excinfo:
response, context = self.do_post({'action_to_resolve':[u'takeaway'],
'take_away_privileges':[u'active'],
'targeted_user':self.admin_user.id},
url='/mod/reports/1/')
self.query_for_users()
assert 'Bad response: 403 FORBIDDEN' in str(excinfo)

View File

@ -0,0 +1,165 @@
# GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import pytest
from mediagoblin.tools import template
from mediagoblin.tests.tools import (fixture_add_user, fixture_media_entry,
fixture_add_comment, fixture_add_comment_report)
from mediagoblin.db.models import (MediaReport, CommentReport, User,
MediaComment,ArchivedReport)
class TestReportFiling:
@pytest.fixture(autouse=True)
def _setup(self, test_app):
self.test_app = test_app
fixture_add_user(u'allie',
privileges=[u'reporter',u'active'])
fixture_add_user(u'natalie',
privileges=[u'active', u'moderator'])
def login(self, username):
self.test_app.post(
'/auth/login/', {
'username': username,
'password': 'toast'})
def logout(self):
self.test_app.get('/auth/logout/')
def do_post(self, data, *context_keys, **kwargs):
url = kwargs.pop('url', '/submit/')
do_follow = kwargs.pop('do_follow', False)
template.clear_test_template_context()
response = self.test_app.post(url, data, **kwargs)
if do_follow:
response.follow()
context_data = template.TEMPLATE_TEST_CONTEXT
for key in context_keys:
context_data = context_data[key]
return response, context_data
def query_for_users(self):
return (User.query.filter(User.username==u'allie').first(),
User.query.filter(User.username==u'natalie').first())
def testMediaReports(self):
self.login(u'allie')
allie_user, natalie_user = self.query_for_users()
allie_id = allie_user.id
media_entry = fixture_media_entry(uploader=natalie_user.id,
state=u'processed')
mid = media_entry.id
media_uri_slug = '/u/{0}/m/{1}/'.format(natalie_user.username,
media_entry.slug)
response = self.test_app.get(media_uri_slug + "report/")
assert response.status == "200 OK"
response, context = self.do_post(
{'report_reason':u'Testing Media Report',
'reporter_id':unicode(allie_id)},url= media_uri_slug + "report/")
assert response.status == "302 FOUND"
media_report = MediaReport.query.first()
allie_user, natalie_user = self.query_for_users()
assert media_report is not None
assert media_report.report_content == u'Testing Media Report'
assert media_report.reporter_id == allie_id
assert media_report.reported_user_id == natalie_user.id
assert media_report.created is not None
assert media_report.discriminator == 'media_report'
def testCommentReports(self):
self.login(u'allie')
allie_user, natalie_user = self.query_for_users()
allie_id = allie_user.id
media_entry = fixture_media_entry(uploader=natalie_user.id,
state=u'processed')
mid = media_entry.id
fixture_add_comment(media_entry=mid,
author=natalie_user.id)
comment = MediaComment.query.first()
comment_uri_slug = '/u/{0}/m/{1}/c/{2}/'.format(natalie_user.username,
media_entry.slug,
comment.id)
response = self.test_app.get(comment_uri_slug + "report/")
assert response.status == "200 OK"
response, context = self.do_post({
'report_reason':u'Testing Comment Report',
'reporter_id':unicode(allie_id)},url= comment_uri_slug + "report/")
assert response.status == "302 FOUND"
comment_report = CommentReport.query.first()
allie_user, natalie_user = self.query_for_users()
assert comment_report is not None
assert comment_report.report_content == u'Testing Comment Report'
assert comment_report.reporter_id == allie_id
assert comment_report.reported_user_id == natalie_user.id
assert comment_report.created is not None
assert comment_report.discriminator == 'comment_report'
def testArchivingReports(self):
self.login(u'natalie')
allie_user, natalie_user = self.query_for_users()
allie_id, natalie_id = allie_user.id, natalie_user.id
fixture_add_comment(author=allie_user.id,
comment=u'Comment will be removed')
test_comment = MediaComment.query.filter(
MediaComment.author==allie_user.id).first()
fixture_add_comment_report(comment=test_comment,
reported_user=allie_user,
report_content=u'Testing Archived Reports #1',
reporter=natalie_user)
comment_report = CommentReport.query.filter(
CommentReport.reported_user==allie_user).first()
assert comment_report.report_content == u'Testing Archived Reports #1'
response, context = self.do_post(
{'action_to_resolve':[u'userban', u'delete'],
'targeted_user':allie_user.id,
'resolution_content':u'This is a test of archiving reports.'},
url='/mod/reports/{0}/'.format(comment_report.id))
assert response.status == "302 FOUND"
self.query_for_users()
archived_report = ArchivedReport.query.first()
assert CommentReport.query.count() == 0
assert archived_report is not None
assert archived_report.report_content == u'Testing Archived Reports #1'
assert archived_report.reporter_id == natalie_id
assert archived_report.reported_user_id == allie_id
assert archived_report.created is not None
assert archived_report.resolved is not None
assert archived_report.result == u'This is a test of archiving reports\
.<br>natalie banned user allie indefinitely.<br>natalie deleted the comment.'
assert archived_report.discriminator == 'archived_report'

View File

@ -24,7 +24,7 @@ import pytest
from mediagoblin.tests.tools import fixture_add_user
from mediagoblin import mg_globals
from mediagoblin.db.models import MediaEntry, User
from mediagoblin.db.models import MediaEntry, User, Privilege
from mediagoblin.tools import template
from mediagoblin.media_types.image import ImageMediaManager
from mediagoblin.media_types.pdf.processing import check_prerequisites as pdf_check_prerequisites
@ -48,10 +48,20 @@ class TestSubmission:
# @as_authenticated_user('chris')
fixture_add_user(privileges=[u'active',u'uploader'])
self.test_user = User.query.filter(User.username==u'chris').first()
self.login()
def our_user(self):
"""
Fetch the user we're submitting with. Every .get() or .post()
invalidates the session; this is a hacky workaround.
"""
#### FIXME: Pytest collects this as a test and runs this.
#### ... it shouldn't. At least it passes, but that's
#### totally stupid.
#### Also if we found a way to make this run it should be a
#### property.
return User.query.filter(User.username==u'chris').first()
def login(self):
self.test_app.post(
'/auth/login/', {
@ -97,10 +107,10 @@ class TestSubmission:
def check_normal_upload(self, title, filename):
response, context = self.do_post({'title': title}, do_follow=True,
**self.upload_data(filename))
self.check_url(response, '/u/{0}/'.format(self.test_user.username))
self.check_url(response, '/u/{0}/'.format(self.our_user().username))
assert 'mediagoblin/user_pages/user.html' in context
# Make sure the media view is at least reachable, logged in...
url = '/u/{0}/m/{1}/'.format(self.test_user.username,
url = '/u/{0}/m/{1}/'.format(self.our_user().username,
title.lower().replace(' ', '-'))
self.test_app.get(url)
# ... and logged out too.
@ -118,7 +128,7 @@ class TestSubmission:
response, context = self.do_post({'title': u'Normal upload 3 (pdf)'},
do_follow=True,
**self.upload_data(GOOD_PDF))
self.check_url(response, '/u/{0}/'.format(self.test_user.username))
self.check_url(response, '/u/{0}/'.format(self.our_user().username))
assert 'mediagoblin/user_pages/user.html' in context
def check_media(self, request, find_data, count=None):
@ -164,7 +174,7 @@ class TestSubmission:
# render and post to the edit page.
edit_url = request.urlgen(
'mediagoblin.edit.edit_media',
user=self.test_user.username, media_id=media_id)
user=self.our_user().username, media_id=media_id)
self.test_app.get(edit_url)
self.test_app.post(edit_url,
{'title': u'Balanced Goblin',
@ -177,7 +187,7 @@ class TestSubmission:
self.check_comments(request, media_id, 0)
comment_url = request.urlgen(
'mediagoblin.user_pages.media_post_comment',
user=self.test_user.username, media_id=media_id)
user=self.our_user().username, media_id=media_id)
response = self.do_post({'comment_content': 'i love this test'},
url=comment_url, do_follow=True)[0]
self.check_comments(request, media_id, 1)
@ -186,7 +196,7 @@ class TestSubmission:
# ---------------------------------------------------
delete_url = request.urlgen(
'mediagoblin.user_pages.media_confirm_delete',
user=self.test_user.username, media_id=media_id)
user=self.our_user().username, media_id=media_id)
# Empty data means don't confirm
response = self.do_post({}, do_follow=True, url=delete_url)[0]
media = self.check_media(request, {'title': u'Balanced Goblin'}, 1)
@ -251,7 +261,7 @@ class TestSubmission:
# they'll be caught as failures during the processing step.
response, context = self.do_post({'title': title}, do_follow=True,
**self.upload_data(filename))
self.check_url(response, '/u/{0}/'.format(self.test_user.username))
self.check_url(response, '/u/{0}/'.format(self.our_user().username))
entry = mg_globals.database.MediaEntry.query.filter_by(title=title).first()
assert entry.state == 'failed'
assert entry.fail_error == u'mediagoblin.processing:BadMediaFail'

View File

@ -25,7 +25,7 @@ from webtest import TestApp
from mediagoblin import mg_globals
from mediagoblin.db.models import User, MediaEntry, Collection, MediaComment, \
CommentSubscription, CommentNotification, Privilege
CommentSubscription, CommentNotification, Privilege, CommentReport
from mediagoblin.tools import testing
from mediagoblin.init.config import read_mediagoblin_config
from mediagoblin.db.base import Session
@ -33,6 +33,8 @@ from mediagoblin.meddleware import BaseMeddleware
from mediagoblin.auth import gen_password_hash
from mediagoblin.gmg_commands.dbupdate import run_dbupdate
from datetime import datetime
MEDIAGOBLIN_TEST_DB_NAME = u'__mediagoblin_tests__'
TEST_SERVER_CONFIG = pkg_resources.resource_filename(
@ -312,3 +314,33 @@ def fixture_add_comment(author=None, media_entry=None, comment=None):
return comment
def fixture_add_comment_report(comment=None, reported_user=None,
reporter=None, created=None, report_content=None):
if comment is None:
comment = fixture_add_comment()
if reported_user is None:
reported_user = fixture_add_user()
if reporter is None:
reporter = fixture_add_user()
if created is None:
created=datetime.now()
if report_content is None:
report_content = \
'Auto-generated test report by user {0}'.format(
reporter)
comment_report = CommentReport(comment=comment,
reported_user = reported_user,
reporter = reporter,
created = created,
report_content=report_content)
comment_report.save()
Session.expunge(comment_report)
return comment_report

View File

@ -52,7 +52,8 @@ def render_400(request, err_msg=None):
_ = pass_to_ugettext
title = _("Bad Request")
if err_msg is None:
err_msg = _("The request sent to the server is invalid, please double check it")
err_msg = _("The request sent to the server is invalid, \
please double check it")
return render_error(request, 400, title, err_msg)
@ -78,9 +79,11 @@ def render_user_banned(request):
and the reason why they have been banned"
"""
user_ban = UserBan.query.get(request.user.id)
if datetime.now()>user_ban.expiration_date:
if (user_ban.expiration_date is not None and
datetime.now()>user_ban.expiration_date):
user_ban.delete()
redirect(request,
return redirect(request,
'index')
return render_to_response(request,
'mediagoblin/banned.html',

View File

@ -162,6 +162,7 @@ def media_home(request, media, page, **kwargs):
@get_media_entry_by_id
@require_active_login
@user_has_privilege(u'commenter')
def media_post_comment(request, media):
"""
recieves POST from a MediaEntry() comment form, saves the comment.
@ -651,13 +652,13 @@ def file_a_report(request, media, comment=None):
'form':form}
if request.method == "POST":
report_table = build_report_object(form,
report_object = build_report_object(form,
media_entry=media,
comment=comment)
# if the object was built successfully, report_table will not be None
if report_table:
report_table.save()
if report_object:
report_object.save()
return redirect(
request,
'index')