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:
parent
e46fb71c1d
commit
dfd66b789c
@ -164,13 +164,13 @@ def register_user(request, register_form):
|
|||||||
user = auth.create_user(register_form)
|
user = auth.create_user(register_form)
|
||||||
|
|
||||||
# give the user the default privileges
|
# give the user the default privileges
|
||||||
default_privileges = [
|
default_privileges = [
|
||||||
Privilege.query.filter(Privilege.privilege_name==u'commenter').first(),
|
Privilege.query.filter(Privilege.privilege_name==u'commenter').first(),
|
||||||
Privilege.query.filter(Privilege.privilege_name==u'uploader').first(),
|
Privilege.query.filter(Privilege.privilege_name==u'uploader').first(),
|
||||||
Privilege.query.filter(Privilege.privilege_name==u'reporter').first()]
|
Privilege.query.filter(Privilege.privilege_name==u'reporter').first()]
|
||||||
user.all_privileges += default_privileges
|
user.all_privileges += default_privileges
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
# log the user in
|
# log the user in
|
||||||
request.session['user_id'] = unicode(user.id)
|
request.session['user_id'] = unicode(user.id)
|
||||||
request.session.save()
|
request.session.save()
|
||||||
|
@ -28,7 +28,7 @@ from migrate.changeset.constraint import UniqueConstraint
|
|||||||
|
|
||||||
from mediagoblin.db.extratypes import JSONEncoded
|
from mediagoblin.db.extratypes import JSONEncoded
|
||||||
from mediagoblin.db.migration_tools import RegisterMigration, inspect_table
|
from mediagoblin.db.migration_tools import RegisterMigration, inspect_table
|
||||||
from mediagoblin.db.models import (MediaEntry, Collection, User,
|
from mediagoblin.db.models import (MediaEntry, Collection, User,
|
||||||
MediaComment, Privilege, ReportBase)
|
MediaComment, Privilege, ReportBase)
|
||||||
|
|
||||||
MIGRATIONS = {}
|
MIGRATIONS = {}
|
||||||
@ -425,7 +425,7 @@ class RequestToken_v0(declarative_base()):
|
|||||||
callback = Column(Unicode, nullable=False, default=u"oob")
|
callback = Column(Unicode, nullable=False, default=u"oob")
|
||||||
created = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
created = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
||||||
updated = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
updated = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
||||||
|
|
||||||
class AccessToken_v0(declarative_base()):
|
class AccessToken_v0(declarative_base()):
|
||||||
"""
|
"""
|
||||||
Model for representing the access tokens
|
Model for representing the access tokens
|
||||||
@ -438,7 +438,7 @@ class AccessToken_v0(declarative_base()):
|
|||||||
request_token = Column(Unicode, ForeignKey(RequestToken_v0.token))
|
request_token = Column(Unicode, ForeignKey(RequestToken_v0.token))
|
||||||
created = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
created = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
||||||
updated = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
updated = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
||||||
|
|
||||||
|
|
||||||
class NonceTimestamp_v0(declarative_base()):
|
class NonceTimestamp_v0(declarative_base()):
|
||||||
"""
|
"""
|
||||||
@ -467,7 +467,7 @@ class ReportBase_v0(declarative_base()):
|
|||||||
reporter_id = Column(Integer, ForeignKey(User.id), nullable=False)
|
reporter_id = Column(Integer, ForeignKey(User.id), nullable=False)
|
||||||
report_content = Column(UnicodeText)
|
report_content = Column(UnicodeText)
|
||||||
reported_user_id = Column(Integer, ForeignKey(User.id), nullable=False)
|
reported_user_id = Column(Integer, ForeignKey(User.id), nullable=False)
|
||||||
created = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
created = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
||||||
discriminator = Column('type', Unicode(50))
|
discriminator = Column('type', Unicode(50))
|
||||||
__mapper_args__ = {'polymorphic_on': discriminator}
|
__mapper_args__ = {'polymorphic_on': discriminator}
|
||||||
|
|
||||||
@ -512,14 +512,14 @@ class Privilege_v0(declarative_base()):
|
|||||||
class PrivilegeUserAssociation_v0(declarative_base()):
|
class PrivilegeUserAssociation_v0(declarative_base()):
|
||||||
__tablename__ = 'core__privileges_users'
|
__tablename__ = 'core__privileges_users'
|
||||||
group_id = Column(
|
group_id = Column(
|
||||||
'core__privilege_id',
|
'core__privilege_id',
|
||||||
Integer,
|
Integer,
|
||||||
ForeignKey(User.id),
|
ForeignKey(User.id),
|
||||||
primary_key=True)
|
primary_key=True)
|
||||||
user_id = Column(
|
user_id = Column(
|
||||||
'core__user_id',
|
'core__user_id',
|
||||||
Integer,
|
Integer,
|
||||||
ForeignKey(Privilege.id),
|
ForeignKey(Privilege.id),
|
||||||
primary_key=True)
|
primary_key=True)
|
||||||
|
|
||||||
@RegisterMigration(15, MIGRATIONS)
|
@RegisterMigration(15, MIGRATIONS)
|
||||||
|
@ -669,7 +669,7 @@ class ReportBase(Base):
|
|||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
reporter_id = Column(Integer, ForeignKey(User.id), nullable=False)
|
reporter_id = Column(Integer, ForeignKey(User.id), nullable=False)
|
||||||
reporter = relationship(
|
reporter = relationship(
|
||||||
User,
|
User,
|
||||||
backref=backref("reports_filed_by",
|
backref=backref("reports_filed_by",
|
||||||
lazy="dynamic",
|
lazy="dynamic",
|
||||||
cascade="all, delete-orphan"),
|
cascade="all, delete-orphan"),
|
||||||
@ -677,7 +677,7 @@ class ReportBase(Base):
|
|||||||
report_content = Column(UnicodeText)
|
report_content = Column(UnicodeText)
|
||||||
reported_user_id = Column(Integer, ForeignKey(User.id), nullable=False)
|
reported_user_id = Column(Integer, ForeignKey(User.id), nullable=False)
|
||||||
reported_user = relationship(
|
reported_user = relationship(
|
||||||
User,
|
User,
|
||||||
backref=backref("reports_filed_on",
|
backref=backref("reports_filed_on",
|
||||||
lazy="dynamic",
|
lazy="dynamic",
|
||||||
cascade="all, delete-orphan"),
|
cascade="all, delete-orphan"),
|
||||||
@ -722,7 +722,7 @@ class MediaReport(ReportBase):
|
|||||||
primary_key=True)
|
primary_key=True)
|
||||||
media_entry_id = Column(Integer, ForeignKey(MediaEntry.id), nullable=False)
|
media_entry_id = Column(Integer, ForeignKey(MediaEntry.id), nullable=False)
|
||||||
media_entry = relationship(
|
media_entry = relationship(
|
||||||
MediaEntry,
|
MediaEntry,
|
||||||
backref=backref("reports_filed_onmod/reports/1/",
|
backref=backref("reports_filed_onmod/reports/1/",
|
||||||
lazy="dynamic",
|
lazy="dynamic",
|
||||||
cascade="all, delete-orphan"))
|
cascade="all, delete-orphan"))
|
||||||
@ -738,7 +738,7 @@ class ArchivedReport(ReportBase):
|
|||||||
|
|
||||||
media_entry_id = Column(Integer, ForeignKey(MediaEntry.id))
|
media_entry_id = Column(Integer, ForeignKey(MediaEntry.id))
|
||||||
media_entry = relationship(
|
media_entry = relationship(
|
||||||
MediaEntry,
|
MediaEntry,
|
||||||
backref=backref("past_reports_filed_on",
|
backref=backref("past_reports_filed_on",
|
||||||
lazy="dynamic"))
|
lazy="dynamic"))
|
||||||
comment_id = Column(Integer, ForeignKey(MediaComment.id))
|
comment_id = Column(Integer, ForeignKey(MediaComment.id))
|
||||||
@ -748,7 +748,7 @@ class ArchivedReport(ReportBase):
|
|||||||
|
|
||||||
resolver_id = Column(Integer, ForeignKey(User.id), nullable=False)
|
resolver_id = Column(Integer, ForeignKey(User.id), nullable=False)
|
||||||
resolver = relationship(
|
resolver = relationship(
|
||||||
User,
|
User,
|
||||||
backref=backref("reports_resolved_by",
|
backref=backref("reports_resolved_by",
|
||||||
lazy="dynamic",
|
lazy="dynamic",
|
||||||
cascade="all, delete-orphan"),
|
cascade="all, delete-orphan"),
|
||||||
@ -759,23 +759,23 @@ class ArchivedReport(ReportBase):
|
|||||||
|
|
||||||
class UserBan(Base):
|
class UserBan(Base):
|
||||||
"""
|
"""
|
||||||
Holds the information on a specific user's ban-state. As long as one of
|
Holds the information on a specific user's ban-state. As long as one of
|
||||||
these is attached to a user, they are banned from accessing mediagoblin.
|
these is attached to a user, they are banned from accessing mediagoblin.
|
||||||
When they try to log in, they are greeted with a page that tells them
|
When they try to log in, they are greeted with a page that tells them
|
||||||
the reason why they are banned and when (if ever) the ban will be
|
the reason why they are banned and when (if ever) the ban will be
|
||||||
lifted
|
lifted
|
||||||
|
|
||||||
:keyword user_id Holds the id of the user this object is
|
:keyword user_id Holds the id of the user this object is
|
||||||
attached to. This is a one-to-one
|
attached to. This is a one-to-one
|
||||||
relationship.
|
relationship.
|
||||||
:keyword expiration_date Holds the date that the ban will be lifted.
|
:keyword expiration_date Holds the date that the ban will be lifted.
|
||||||
If this is null, the ban is permanent
|
If this is null, the ban is permanent
|
||||||
unless a moderator manually lifts it.
|
unless a moderator manually lifts it.
|
||||||
:keyword reason Holds the reason why the user was banned.
|
:keyword reason Holds the reason why the user was banned.
|
||||||
"""
|
"""
|
||||||
__tablename__ = 'core__user_bans'
|
__tablename__ = 'core__user_bans'
|
||||||
|
|
||||||
user_id = Column(Integer, ForeignKey(User.id), nullable=False,
|
user_id = Column(Integer, ForeignKey(User.id), nullable=False,
|
||||||
primary_key=True)
|
primary_key=True)
|
||||||
expiration_date = Column(DateTime)
|
expiration_date = Column(DateTime)
|
||||||
reason = Column(UnicodeText, nullable=False)
|
reason = Column(UnicodeText, nullable=False)
|
||||||
@ -785,21 +785,21 @@ class Privilege(Base):
|
|||||||
"""
|
"""
|
||||||
The Privilege table holds all of the different privileges a user can hold.
|
The Privilege table holds all of the different privileges a user can hold.
|
||||||
If a user 'has' a privilege, the User object is in a relationship with the
|
If a user 'has' a privilege, the User object is in a relationship with the
|
||||||
privilege object.
|
privilege object.
|
||||||
|
|
||||||
:keyword privilege_name Holds a unicode object that is the recognizable
|
:keyword privilege_name Holds a unicode object that is the recognizable
|
||||||
name of this privilege. This is the column
|
name of this privilege. This is the column
|
||||||
used for identifying whether or not a user
|
used for identifying whether or not a user
|
||||||
has a necessary privilege or not.
|
has a necessary privilege or not.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
__tablename__ = 'core__privileges'
|
__tablename__ = 'core__privileges'
|
||||||
|
|
||||||
id = Column(Integer, nullable=False, primary_key=True)
|
id = Column(Integer, nullable=False, primary_key=True)
|
||||||
privilege_name = Column(Unicode, nullable=False, unique=True)
|
privilege_name = Column(Unicode, nullable=False, unique=True)
|
||||||
all_users = relationship(
|
all_users = relationship(
|
||||||
User,
|
User,
|
||||||
backref='all_privileges',
|
backref='all_privileges',
|
||||||
secondary="core__privileges_users")
|
secondary="core__privileges_users")
|
||||||
|
|
||||||
def __init__(self, privilege_name):
|
def __init__(self, privilege_name):
|
||||||
@ -818,25 +818,25 @@ class PrivilegeUserAssociation(Base):
|
|||||||
'''
|
'''
|
||||||
This table holds the many-to-many relationship between User and Privilege
|
This table holds the many-to-many relationship between User and Privilege
|
||||||
'''
|
'''
|
||||||
|
|
||||||
__tablename__ = 'core__privileges_users'
|
__tablename__ = 'core__privileges_users'
|
||||||
|
|
||||||
privilege_id = Column(
|
privilege_id = Column(
|
||||||
'core__privilege_id',
|
'core__privilege_id',
|
||||||
Integer,
|
Integer,
|
||||||
ForeignKey(User.id),
|
ForeignKey(User.id),
|
||||||
primary_key=True)
|
primary_key=True)
|
||||||
user_id = Column(
|
user_id = Column(
|
||||||
'core__user_id',
|
'core__user_id',
|
||||||
Integer,
|
Integer,
|
||||||
ForeignKey(Privilege.id),
|
ForeignKey(Privilege.id),
|
||||||
primary_key=True)
|
primary_key=True)
|
||||||
|
|
||||||
MODELS = [
|
MODELS = [
|
||||||
User, MediaEntry, Tag, MediaTag, MediaComment, Collection, CollectionItem,
|
User, MediaEntry, Tag, MediaTag, MediaComment, Collection, CollectionItem,
|
||||||
MediaFile, FileKeynames, MediaAttachmentFile, ProcessingMetaData,
|
MediaFile, FileKeynames, MediaAttachmentFile, ProcessingMetaData,
|
||||||
Notification, CommentNotification, ProcessingNotification, Client,
|
Notification, CommentNotification, ProcessingNotification, Client,
|
||||||
CommentSubscription, ReportBase, CommentReport, MediaReport, UserBan,
|
CommentSubscription, ReportBase, CommentReport, MediaReport, UserBan,
|
||||||
Privilege, PrivilegeUserAssociation, ArchivedReport,
|
Privilege, PrivilegeUserAssociation, ArchivedReport,
|
||||||
RequestToken, AccessToken, NonceTimestamp]
|
RequestToken, AccessToken, NonceTimestamp]
|
||||||
|
|
||||||
@ -854,10 +854,10 @@ MODELS = [
|
|||||||
|
|
||||||
FOUNDATIONS = {User:user_foundations}
|
FOUNDATIONS = {User:user_foundations}
|
||||||
"""
|
"""
|
||||||
privilege_foundations = [{'privilege_name':u'admin'},
|
privilege_foundations = [{'privilege_name':u'admin'},
|
||||||
{'privilege_name':u'moderator'},
|
{'privilege_name':u'moderator'},
|
||||||
{'privilege_name':u'uploader'},
|
{'privilege_name':u'uploader'},
|
||||||
{'privilege_name':u'reporter'},
|
{'privilege_name':u'reporter'},
|
||||||
{'privilege_name':u'commenter'},
|
{'privilege_name':u'commenter'},
|
||||||
{'privilege_name':u'active'}]
|
{'privilege_name':u'active'}]
|
||||||
FOUNDATIONS = {Privilege:privilege_foundations}
|
FOUNDATIONS = {Privilege:privilege_foundations}
|
||||||
|
@ -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
|
does_exist = Session.query(Collection.id).filter(filt).first() is not None
|
||||||
return does_exist
|
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__':
|
if __name__ == '__main__':
|
||||||
from mediagoblin.db.open import setup_connection_and_db_from_config
|
from mediagoblin.db.open import setup_connection_and_db_from_config
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ from mediagoblin import mg_globals as mgg
|
|||||||
from mediagoblin import messages
|
from mediagoblin import messages
|
||||||
from mediagoblin.db.models import (MediaEntry, User, MediaComment,
|
from mediagoblin.db.models import (MediaEntry, User, MediaComment,
|
||||||
UserBan, Privilege)
|
UserBan, Privilege)
|
||||||
from mediagoblin.tools.response import (redirect, render_404,
|
from mediagoblin.tools.response import (redirect, render_404,
|
||||||
render_user_banned, json_response)
|
render_user_banned, json_response)
|
||||||
from mediagoblin.tools.translate import pass_to_ugettext as _
|
from mediagoblin.tools.translate import pass_to_ugettext as _
|
||||||
|
|
||||||
@ -358,7 +358,7 @@ def oauth_required(controller):
|
|||||||
error = "Missing required parameter."
|
error = "Missing required parameter."
|
||||||
return json_response({"error": error}, status=400)
|
return json_response({"error": error}, status=400)
|
||||||
|
|
||||||
|
|
||||||
request_validator = GMGRequestValidator()
|
request_validator = GMGRequestValidator()
|
||||||
resource_endpoint = ResourceEndpoint(request_validator)
|
resource_endpoint = ResourceEndpoint(request_validator)
|
||||||
valid, request = resource_endpoint.validate_protected_resource_request(
|
valid, request = resource_endpoint.validate_protected_resource_request(
|
||||||
|
@ -55,7 +55,7 @@ def adduser(args):
|
|||||||
entry.pw_hash = auth.gen_password_hash(args.password)
|
entry.pw_hash = auth.gen_password_hash(args.password)
|
||||||
entry.status = u'active'
|
entry.status = u'active'
|
||||||
entry.email_verified = True
|
entry.email_verified = True
|
||||||
default_privileges = [
|
default_privileges = [
|
||||||
db.Privilege.query.filter(
|
db.Privilege.query.filter(
|
||||||
db.Privilege.privilege_name==u'commenter').one(),
|
db.Privilege.privilege_name==u'commenter').one(),
|
||||||
db.Privilege.query.filter(
|
db.Privilege.query.filter(
|
||||||
|
@ -28,7 +28,7 @@ class MultiCheckboxField(wtforms.SelectMultipleField):
|
|||||||
|
|
||||||
Iterating the field will produce subfields, allowing custom rendering of
|
Iterating the field will produce subfields, allowing custom rendering of
|
||||||
the enclosed checkbox fields.
|
the enclosed checkbox fields.
|
||||||
|
|
||||||
code from http://wtforms.simplecodes.com/docs/1.0.4/specific_problems.html
|
code from http://wtforms.simplecodes.com/docs/1.0.4/specific_problems.html
|
||||||
"""
|
"""
|
||||||
widget = wtforms.widgets.ListWidget(prefix_label=False)
|
widget = wtforms.widgets.ListWidget(prefix_label=False)
|
||||||
@ -40,7 +40,7 @@ class PrivilegeAddRemoveForm(wtforms.Form):
|
|||||||
|
|
||||||
class ReportResolutionForm(wtforms.Form):
|
class ReportResolutionForm(wtforms.Form):
|
||||||
action_to_resolve = MultiCheckboxField(
|
action_to_resolve = MultiCheckboxField(
|
||||||
_(u'What action will you take to resolve the report?'),
|
_(u'What action will you take to resolve the report?'),
|
||||||
validators=[wtforms.validators.optional()],
|
validators=[wtforms.validators.optional()],
|
||||||
choices=ACTION_CHOICES)
|
choices=ACTION_CHOICES)
|
||||||
targeted_user = wtforms.HiddenField('',
|
targeted_user = wtforms.HiddenField('',
|
||||||
|
@ -31,17 +31,15 @@ def take_punitive_actions(request, form, report, user):
|
|||||||
# punitive actions that a moderator could take.
|
# punitive actions that a moderator could take.
|
||||||
if u'takeaway' in form.action_to_resolve.data:
|
if u'takeaway' in form.action_to_resolve.data:
|
||||||
for privilege_name in form.take_away_privileges.data:
|
for privilege_name in form.take_away_privileges.data:
|
||||||
privilege = Privilege.query.filter(
|
take_away_privileges(user.username, privilege_name)
|
||||||
Privilege.privilege_name==privilege_name).one()
|
|
||||||
form.resolution_content.data += \
|
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,
|
request.user.username,
|
||||||
user.username,
|
user.username,
|
||||||
privilege.privilege_name)
|
privilege_name)
|
||||||
user.all_privileges.remove(privilege)
|
|
||||||
|
|
||||||
# If the moderator elects to ban the user, a new instance of user_ban
|
# If the moderator elects to ban the user, a new instance of user_ban
|
||||||
# will be created.
|
# will be created.
|
||||||
if u'userban' in form.action_to_resolve.data:
|
if u'userban' in form.action_to_resolve.data:
|
||||||
reason = form.resolution_content.data + \
|
reason = form.resolution_content.data + \
|
||||||
"<br>"+request.user.username
|
"<br>"+request.user.username
|
||||||
@ -51,7 +49,7 @@ def take_punitive_actions(request, form, report, user):
|
|||||||
reason= form.why_user_was_banned.data
|
reason= form.why_user_was_banned.data
|
||||||
)
|
)
|
||||||
Session.add(user_ban)
|
Session.add(user_ban)
|
||||||
|
|
||||||
if form.user_banned_until.data is not None:
|
if form.user_banned_until.data is not None:
|
||||||
form.resolution_content.data += \
|
form.resolution_content.data += \
|
||||||
u"<br>%s banned user %s until %s." % (
|
u"<br>%s banned user %s until %s." % (
|
||||||
@ -86,17 +84,17 @@ def take_punitive_actions(request, form, report, user):
|
|||||||
deleted_comment = report.comment
|
deleted_comment = report.comment
|
||||||
Session.delete(deleted_comment)
|
Session.delete(deleted_comment)
|
||||||
form.resolution_content.data += \
|
form.resolution_content.data += \
|
||||||
u"<br>%s deleted the comment" % (
|
u"<br>%s deleted the comment." % (
|
||||||
request.user.username)
|
request.user.username)
|
||||||
elif u'delete' in form.action_to_resolve.data and \
|
elif u'delete' in form.action_to_resolve.data and \
|
||||||
report.is_media_entry_report():
|
report.is_media_entry_report():
|
||||||
deleted_media = report.media_entry
|
deleted_media = report.media_entry
|
||||||
Session.delete(deleted_media)
|
Session.delete(deleted_media)
|
||||||
form.resolution_content.data += \
|
form.resolution_content.data += \
|
||||||
u"<br>%s deleted the media entry" % (
|
u"<br>%s deleted the media entry." % (
|
||||||
request.user.username)
|
request.user.username)
|
||||||
|
|
||||||
# If the moderator didn't delete the content we then attach the
|
# If the moderator didn't delete the content we then attach the
|
||||||
# content to the archived report. We also have to actively delete the
|
# content to the archived report. We also have to actively delete the
|
||||||
# old report, since it won't be deleted by cascading.
|
# old report, since it won't be deleted by cascading.
|
||||||
elif report.is_comment_report():
|
elif report.is_comment_report():
|
||||||
@ -133,3 +131,34 @@ def take_punitive_actions(request, form, report, user):
|
|||||||
request,
|
request,
|
||||||
'mediagoblin.moderation.reports_detail',
|
'mediagoblin.moderation.reports_detail',
|
||||||
report_id=report.id)
|
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:]))
|
||||||
|
|
||||||
|
@ -19,12 +19,12 @@ from werkzeug.exceptions import Forbidden
|
|||||||
from mediagoblin.db.models import (MediaEntry, User, MediaComment, \
|
from mediagoblin.db.models import (MediaEntry, User, MediaComment, \
|
||||||
CommentReport, ReportBase, Privilege, \
|
CommentReport, ReportBase, Privilege, \
|
||||||
UserBan, ArchivedReport)
|
UserBan, ArchivedReport)
|
||||||
from mediagoblin.db.util import user_privileges_to_dictionary
|
|
||||||
from mediagoblin.decorators import (require_admin_or_moderator_login, \
|
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.tools.response import render_to_response, redirect
|
||||||
from mediagoblin.moderation import forms as moderation_forms
|
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
|
from datetime import datetime
|
||||||
|
|
||||||
@require_admin_or_moderator_login
|
@require_admin_or_moderator_login
|
||||||
@ -86,7 +86,7 @@ def moderation_users_detail(request):
|
|||||||
@require_admin_or_moderator_login
|
@require_admin_or_moderator_login
|
||||||
def moderation_reports_panel(request):
|
def moderation_reports_panel(request):
|
||||||
'''
|
'''
|
||||||
Show the global panel for monitoring reports filed against comments or
|
Show the global panel for monitoring reports filed against comments or
|
||||||
media entries for this instance.
|
media entries for this instance.
|
||||||
'''
|
'''
|
||||||
report_list = ReportBase.query.filter(
|
report_list = ReportBase.query.filter(
|
||||||
@ -115,7 +115,7 @@ def moderation_reports_detail(request):
|
|||||||
|
|
||||||
form.take_away_privileges.choices = [
|
form.take_away_privileges.choices = [
|
||||||
(s.privilege_name,s.privilege_name.title()) \
|
(s.privilege_name,s.privilege_name.title()) \
|
||||||
for s in report.reported_user.all_privileges
|
for s in report.reported_user.all_privileges
|
||||||
]
|
]
|
||||||
|
|
||||||
if request.method == "POST" and form.validate() and not (
|
if request.method == "POST" and form.validate() and not (
|
||||||
@ -134,7 +134,7 @@ def moderation_reports_detail(request):
|
|||||||
{'report':report,
|
{'report':report,
|
||||||
'form':form})
|
'form':form})
|
||||||
|
|
||||||
@require_admin_or_moderator_login
|
@user_has_privilege(u'admin')
|
||||||
@active_user_from_url
|
@active_user_from_url
|
||||||
def give_or_take_away_privilege(request, url_user):
|
def give_or_take_away_privilege(request, url_user):
|
||||||
'''
|
'''
|
||||||
@ -144,12 +144,13 @@ def give_or_take_away_privilege(request, url_user):
|
|||||||
if request.method == "POST" and form.validate():
|
if request.method == "POST" and form.validate():
|
||||||
privilege = Privilege.query.filter(
|
privilege = Privilege.query.filter(
|
||||||
Privilege.privilege_name==form.privilege_name.data).one()
|
Privilege.privilege_name==form.privilege_name.data).one()
|
||||||
if privilege in url_user.all_privileges:
|
if not take_away_privileges(
|
||||||
url_user.all_privileges.remove(privilege)
|
url_user.username, form.privilege_name.data):
|
||||||
else:
|
|
||||||
url_user.all_privileges.append(privilege)
|
give_privileges(url_user.username, form.privilege_name.data)
|
||||||
url_user.save()
|
url_user.save()
|
||||||
return redirect(
|
|
||||||
request,
|
return redirect(
|
||||||
'mediagoblin.moderation.users_detail',
|
request,
|
||||||
user=url_user.username)
|
'mediagoblin.moderation.users_detail',
|
||||||
|
user=url_user.username)
|
||||||
|
@ -17,12 +17,19 @@
|
|||||||
#}
|
#}
|
||||||
{% extends "mediagoblin/base.html" %}
|
{% extends "mediagoblin/base.html" %}
|
||||||
|
|
||||||
{% block title %}You are Banned.{% endblock %}
|
{% block title %}{% trans %}You are Banned.{% endtrans %}{% endblock %}
|
||||||
|
|
||||||
{% block mediagoblin_content %}
|
{% block mediagoblin_content %}
|
||||||
<img class="right_align" src="{{ request.staticdirect('/images/404.png') }}"
|
<img class="right_align" src="{{ request.staticdirect('/images/404.png') }}"
|
||||||
alt="{% trans %}Image of goblin stressing out{% endtrans %}" />
|
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>
|
<p>{{ reason|safe }}</p>
|
||||||
<div class="clear"></div>
|
<div class="clear"></div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<p>
|
<p>
|
||||||
{% trans %}Here you can track the state of media being processed on this instance.{% endtrans %}
|
{% trans %}Here you can track the state of media being processed on this instance.{% endtrans %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>{% trans %}Media in-processing{% endtrans %}</h2>
|
<h2>{% trans %}Media in-processing{% endtrans %}</h2>
|
||||||
|
|
||||||
{% if processing_entries.count() %}
|
{% if processing_entries.count() %}
|
||||||
@ -56,7 +56,7 @@
|
|||||||
</table>
|
</table>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p><em>{% trans %}No media in-processing{% endtrans %}</em></p>
|
<p><em>{% trans %}No media in-processing{% endtrans %}</em></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h2>{% trans %}These uploads failed to process:{% endtrans %}</h2>
|
<h2>{% trans %}These uploads failed to process:{% endtrans %}</h2>
|
||||||
{% if failed_entries.count() %}
|
{% if failed_entries.count() %}
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
title="Return to Reports Panel">
|
title="Return to Reports Panel">
|
||||||
{% trans %}Return to Reports Panel{% endtrans %}</a>
|
{% trans %}Return to Reports Panel{% endtrans %}</a>
|
||||||
<h2>{% trans %}Report{% endtrans %} #{{ report.id }}</h2>
|
<h2>{% trans %}Report{% endtrans %} #{{ report.id }}</h2>
|
||||||
{% if report.is_comment_report() or
|
{% if report.is_comment_report() or
|
||||||
(report.is_archived_report() and report.comment) %}
|
(report.is_archived_report() and report.comment) %}
|
||||||
|
|
||||||
{% trans %}Reported comment{% endtrans %}:
|
{% trans %}Reported comment{% endtrans %}:
|
||||||
@ -60,7 +60,7 @@
|
|||||||
{% endautoescape %}
|
{% endautoescape %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% elif report.is_media_entry_report() or
|
{% elif report.is_media_entry_report() or
|
||||||
(report.is_archived_report() and report.media_entry) %}
|
(report.is_archived_report() and report.media_entry) %}
|
||||||
|
|
||||||
{% set media_entry = report.media_entry %}
|
{% set media_entry = report.media_entry %}
|
||||||
@ -89,7 +89,7 @@
|
|||||||
'mediagoblin.moderation.users_detail',
|
'mediagoblin.moderation.users_detail',
|
||||||
user=report.reporter.username),
|
user=report.reporter.username),
|
||||||
user_name=report.reported_user.username %}
|
user_name=report.reported_user.username %}
|
||||||
CONTENT BY
|
CONTENT BY
|
||||||
<a href="{{ user_url }}"> {{ user_name }}</a>
|
<a href="{{ user_url }}"> {{ user_name }}</a>
|
||||||
HAS BEEN DELETED
|
HAS BEEN DELETED
|
||||||
{% endtrans %}
|
{% endtrans %}
|
||||||
@ -100,8 +100,8 @@
|
|||||||
class="report_wrapper">
|
class="report_wrapper">
|
||||||
<div class="report_author">
|
<div class="report_author">
|
||||||
<img src="{{ request.staticdirect(
|
<img src="{{ request.staticdirect(
|
||||||
'/images/icon_clipboard_alert.png') }}"
|
'/images/icon_clipboard_alert.png') }}"
|
||||||
alt="Under a GNU LGPL v.3 or Creative Commons BY-SA 3.0 license.
|
alt="Under a GNU LGPL v.3 or Creative Commons BY-SA 3.0 license.
|
||||||
Distributed by the GNOME project http://www.gnome.org" />
|
Distributed by the GNOME project http://www.gnome.org" />
|
||||||
<a href="{{ request.urlgen('mediagoblin.moderation.users_detail',
|
<a href="{{ request.urlgen('mediagoblin.moderation.users_detail',
|
||||||
user=report.reporter.username) }}"
|
user=report.reporter.username) }}"
|
||||||
@ -160,7 +160,7 @@ $(document).ready(function() {
|
|||||||
$('ul#action_to_resolve li input:not(:checked)').each(function() {
|
$('ul#action_to_resolve li input:not(:checked)').each(function() {
|
||||||
$.each(hidden_input_names[$(this).val()], function(index, name){
|
$.each(hidden_input_names[$(this).val()], function(index, name){
|
||||||
$('label[for='+name+']').hide();
|
$('label[for='+name+']').hide();
|
||||||
$('#'+name).hide();
|
$('#'+name).hide();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -176,12 +176,12 @@ $(document).ready(function() {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% elif not (report.reported_user.has_privilege('admin')) %}
|
{% elif not (report.reported_user.has_privilege('admin')) %}
|
||||||
<h2><img src="{{ request.staticdirect('/images/icon_clipboard.png') }}"
|
<h2><img src="{{ request.staticdirect('/images/icon_clipboard.png') }}"
|
||||||
alt="Under a GNU LGPL v.3 or Creative Commons BY-SA 3.0 license.
|
alt="Under a GNU LGPL v.3 or Creative Commons BY-SA 3.0 license.
|
||||||
Distributed by the GNOME project http://www.gnome.org" />
|
Distributed by the GNOME project http://www.gnome.org" />
|
||||||
{% trans %}Status{% endtrans %}:
|
{% trans %}Status{% endtrans %}:
|
||||||
</h2>
|
</h2>
|
||||||
<b>{% trans %}RESOLVED{% endtrans %}</b>
|
<b>{% trans %}RESOLVED{% endtrans %}</b>
|
||||||
{{ report.resolved.strftime("%I:%M%p %Y-%m-%d") }}
|
{{ report.resolved.strftime("%I:%M%p %Y-%m-%d") }}
|
||||||
{% autoescape False %}
|
{% autoescape False %}
|
||||||
<p>{{ report.result }}</p>
|
<p>{{ report.result }}</p>
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
Here you can look up open reports that have been filed by users.
|
Here you can look up open reports that have been filed by users.
|
||||||
{% endtrans %}
|
{% endtrans %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>{% trans %}Active Reports Filed{% endtrans %}</h2>
|
<h2>{% trans %}Active Reports Filed{% endtrans %}</h2>
|
||||||
|
|
||||||
{% if report_list.count() %}
|
{% if report_list.count() %}
|
||||||
@ -46,22 +46,22 @@
|
|||||||
<tr>
|
<tr>
|
||||||
{% if report.discriminator == "comment_report" %}
|
{% if report.discriminator == "comment_report" %}
|
||||||
<td>
|
<td>
|
||||||
<img
|
<img
|
||||||
src="{{ request.staticdirect('/images/icon_clipboard_alert.png') }}"
|
src="{{ request.staticdirect('/images/icon_clipboard_alert.png') }}"
|
||||||
alt="Under a GNU LGPL v.3 or Creative Commons BY-SA 3.0 license.
|
alt="Under a GNU LGPL v.3 or Creative Commons BY-SA 3.0 license.
|
||||||
Distributed by the GNOME project http://www.gnome.org" />
|
Distributed by the GNOME project http://www.gnome.org" />
|
||||||
<a href="{{ request.urlgen(
|
<a href="{{ request.urlgen(
|
||||||
'mediagoblin.moderation.reports_detail',
|
'mediagoblin.moderation.reports_detail',
|
||||||
report_id=report.id) }}">
|
report_id=report.id) }}">
|
||||||
{% trans report_id=report.id %}
|
{% trans report_id=report.id %}
|
||||||
Comment Report #{{ report_id }}
|
Comment Report #{{ report_id }}
|
||||||
{% endtrans %}
|
{% endtrans %}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
{% elif report.discriminator == "media_report" %}
|
{% elif report.discriminator == "media_report" %}
|
||||||
<td>
|
<td>
|
||||||
<img
|
<img
|
||||||
src="{{ request.staticdirect('/images/icon_clipboard_alert.png') }}"
|
src="{{ request.staticdirect('/images/icon_clipboard_alert.png') }}"
|
||||||
alt="Under a GNU LGPL v.3 or Creative Commons BY-SA 3.0 license.
|
alt="Under a GNU LGPL v.3 or Creative Commons BY-SA 3.0 license.
|
||||||
Distributed by the GNOME project http://www.gnome.org" />
|
Distributed by the GNOME project http://www.gnome.org" />
|
||||||
<a href="{{ request.urlgen(
|
<a href="{{ request.urlgen(
|
||||||
@ -97,8 +97,8 @@
|
|||||||
{% for report in closed_report_list %}
|
{% for report in closed_report_list %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<img
|
<img
|
||||||
src="{{ request.staticdirect('/images/icon_clipboard.png') }}"
|
src="{{ request.staticdirect('/images/icon_clipboard.png') }}"
|
||||||
alt="Under a GNU LGPL v.3 or Creative Commons BY-SA 3.0 license.
|
alt="Under a GNU LGPL v.3 or Creative Commons BY-SA 3.0 license.
|
||||||
Distributed by the GNOME project http://www.gnome.org" />
|
Distributed by the GNOME project http://www.gnome.org" />
|
||||||
<a href="{{ request.urlgen('mediagoblin.moderation.reports_detail',
|
<a href="{{ request.urlgen('mediagoblin.moderation.reports_detail',
|
||||||
@ -118,5 +118,5 @@
|
|||||||
</table>
|
</table>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p><em>{% trans %}No closed reports found.{% endtrans %}</em></p>
|
<p><em>{% trans %}No closed reports found.{% endtrans %}</em></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -130,9 +130,9 @@
|
|||||||
<a class="right_align">{{ user.username }}'s report history</a>
|
<a class="right_align">{{ user.username }}'s report history</a>
|
||||||
<span class=clear></span>
|
<span class=clear></span>
|
||||||
<h2>{{ user.username }}'s Privileges</h2>
|
<h2>{{ user.username }}'s Privileges</h2>
|
||||||
{% if request.user.has_privilege('admin') and not user_banned and
|
{% if request.user.has_privilege('admin') and not user_banned and
|
||||||
not user.id == request.user.id %}
|
not user.id == request.user.id %}
|
||||||
<input type=button class="button_action right_align"
|
<input type=button class="button_action right_align"
|
||||||
value="Ban User" />
|
value="Ban User" />
|
||||||
{% elif request.user.has_privilege('admin') and
|
{% elif request.user.has_privilege('admin') and
|
||||||
not user.id == request.user.id %}
|
not user.id == request.user.id %}
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
Here you can look up users in order to take punitive actions on them.
|
Here you can look up users in order to take punitive actions on them.
|
||||||
{% endtrans %}
|
{% endtrans %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>{% trans %}Active Users{% endtrans %}</h2>
|
<h2>{% trans %}Active Users{% endtrans %}</h2>
|
||||||
|
|
||||||
{% if user_list.count() %}
|
{% if user_list.count() %}
|
||||||
@ -57,5 +57,5 @@
|
|||||||
</table>
|
</table>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p><em>{% trans %}No users found.{% endtrans %}</em></p>
|
<p><em>{% trans %}No users found.{% endtrans %}</em></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -86,7 +86,7 @@
|
|||||||
{% autoescape False %}
|
{% autoescape False %}
|
||||||
<p>{{ media.description_html }}</p>
|
<p>{{ media.description_html }}</p>
|
||||||
{% endautoescape %}
|
{% endautoescape %}
|
||||||
{% if comments %}
|
{% if comments and request.user.has_privilege('commenter') %}
|
||||||
{% if app_config['allow_comments'] %}
|
{% if app_config['allow_comments'] %}
|
||||||
<a
|
<a
|
||||||
{% if not request.user %}
|
{% if not request.user %}
|
||||||
|
@ -26,15 +26,15 @@
|
|||||||
{%- set comment_author_url = request.urlgen(
|
{%- set comment_author_url = request.urlgen(
|
||||||
'mediagoblin.user_pages.user_home',
|
'mediagoblin.user_pages.user_home',
|
||||||
user=comment_author.username) %}
|
user=comment_author.username) %}
|
||||||
{%- set comment_url = request.urlgen(
|
{%- set comment_url = request.urlgen(
|
||||||
'mediagoblin.user_pages.media_home.view_comment',
|
'mediagoblin.user_pages.media_home.view_comment',
|
||||||
comment=comment.id,
|
comment=comment.id,
|
||||||
user=media.get_uploader.username,
|
user=media.get_uploader.username,
|
||||||
media=media.slug_or_id) %}
|
media=media.slug_or_id) %}
|
||||||
<div id="comment-{{ comment.id }}"
|
<div id="comment-{{ comment.id }}"
|
||||||
class="comment_wrapper">
|
class="comment_wrapper">
|
||||||
<div class="comment_author">
|
<div class="comment_author">
|
||||||
<img
|
<img
|
||||||
src="{{ request.staticdirect('/images/icon_comment.png') }}" />
|
src="{{ request.staticdirect('/images/icon_comment.png') }}" />
|
||||||
<a href="{{ comment_author_url }}"
|
<a href="{{ comment_author_url }}"
|
||||||
class="comment_authorlink">
|
class="comment_authorlink">
|
||||||
@ -42,7 +42,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<a href="{{ comment_url }}"
|
<a href="{{ comment_url }}"
|
||||||
class="comment_whenlink">
|
class="comment_whenlink">
|
||||||
<span
|
<span
|
||||||
title='{{- comment.created.strftime("%I:%M%p %Y-%m-%d") -}}'>
|
title='{{- comment.created.strftime("%I:%M%p %Y-%m-%d") -}}'>
|
||||||
|
|
||||||
{%- trans formatted_time=timesince(comment.created) -%}
|
{%- trans formatted_time=timesince(comment.created) -%}
|
||||||
@ -59,19 +59,19 @@
|
|||||||
{% elif media is defined %}
|
{% elif media is defined %}
|
||||||
<h3>{% trans %}Reporting this Media Entry{% endtrans %}</h3>
|
<h3>{% trans %}Reporting this Media Entry{% endtrans %}</h3>
|
||||||
<div class="media_thumbnail">
|
<div class="media_thumbnail">
|
||||||
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
|
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
|
||||||
user=media.get_uploader.username,
|
user=media.get_uploader.username,
|
||||||
media=media.slug_or_id) }}">
|
media=media.slug_or_id) }}">
|
||||||
<img src="{{ media.thumb_url }}"/></a>
|
<img src="{{ media.thumb_url }}"/></a>
|
||||||
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
|
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home',
|
||||||
user=media.get_uploader.username,
|
user=media.get_uploader.username,
|
||||||
media=media.slug_or_id) }}"
|
media=media.slug_or_id) }}"
|
||||||
class=thumb_entry_title>{{ media.title }}</a>
|
class=thumb_entry_title>{{ media.title }}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class=clear></div>
|
<div class=clear></div>
|
||||||
{%- trans user_url = request.urlgen('mediagoblin.user_pages.user_home', user=media.get_uploader.username),
|
{%- trans user_url = request.urlgen('mediagoblin.user_pages.user_home', user=media.get_uploader.username),
|
||||||
username = media.get_uploader.username %}
|
username = media.get_uploader.username %}
|
||||||
❖ Published by <a href="{{ user_url }}"
|
❖ Published by <a href="{{ user_url }}"
|
||||||
class="comment_authorlink">{{ username }}</a>
|
class="comment_authorlink">{{ username }}</a>
|
||||||
{% endtrans %}
|
{% endtrans %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
{% block report_content -%}
|
{% block report_content -%}
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
{% if not request.user -%}
|
{% if not request.user -%}
|
||||||
href="{{ request.urlgen('mediagoblin.auth.login') }}"
|
href="{{ request.urlgen('mediagoblin.auth.login') }}"
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -330,6 +330,13 @@ def test_authentication_views(test_app):
|
|||||||
'next' : '/u/chris/'})
|
'next' : '/u/chris/'})
|
||||||
assert urlparse.urlsplit(response.location)[2] == '/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()
|
@pytest.fixture()
|
||||||
def authentication_disabled_app(request):
|
def authentication_disabled_app(request):
|
||||||
|
194
mediagoblin/tests/test_moderation.py
Normal file
194
mediagoblin/tests/test_moderation.py
Normal 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/')
|
@ -127,7 +127,6 @@ otherperson@example.com\n\nSGkgb3RoZXJwZXJzb24sCmNocmlzIGNvbW1lbnRlZCBvbiB5b3VyI
|
|||||||
else:
|
else:
|
||||||
assert mail.EMAIL_TEST_MBOX_INBOX == []
|
assert mail.EMAIL_TEST_MBOX_INBOX == []
|
||||||
|
|
||||||
mail.EMAIL_TEST_MBOX_INBOX = []
|
|
||||||
|
|
||||||
# Save the ids temporarily because of DetachedInstanceError
|
# Save the ids temporarily because of DetachedInstanceError
|
||||||
notification_id = notification.id
|
notification_id = notification.id
|
||||||
|
206
mediagoblin/tests/test_privileges.py
Normal file
206
mediagoblin/tests/test_privileges.py
Normal 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)
|
165
mediagoblin/tests/test_reporting.py
Normal file
165
mediagoblin/tests/test_reporting.py
Normal 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'
|
||||||
|
|
@ -24,7 +24,7 @@ import pytest
|
|||||||
|
|
||||||
from mediagoblin.tests.tools import fixture_add_user
|
from mediagoblin.tests.tools import fixture_add_user
|
||||||
from mediagoblin import mg_globals
|
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.tools import template
|
||||||
from mediagoblin.media_types.image import ImageMediaManager
|
from mediagoblin.media_types.image import ImageMediaManager
|
||||||
from mediagoblin.media_types.pdf.processing import check_prerequisites as pdf_check_prerequisites
|
from mediagoblin.media_types.pdf.processing import check_prerequisites as pdf_check_prerequisites
|
||||||
@ -48,10 +48,20 @@ class TestSubmission:
|
|||||||
# @as_authenticated_user('chris')
|
# @as_authenticated_user('chris')
|
||||||
fixture_add_user(privileges=[u'active',u'uploader'])
|
fixture_add_user(privileges=[u'active',u'uploader'])
|
||||||
|
|
||||||
self.test_user = User.query.filter(User.username==u'chris').first()
|
|
||||||
|
|
||||||
self.login()
|
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):
|
def login(self):
|
||||||
self.test_app.post(
|
self.test_app.post(
|
||||||
'/auth/login/', {
|
'/auth/login/', {
|
||||||
@ -97,10 +107,10 @@ class TestSubmission:
|
|||||||
def check_normal_upload(self, title, filename):
|
def check_normal_upload(self, title, filename):
|
||||||
response, context = self.do_post({'title': title}, do_follow=True,
|
response, context = self.do_post({'title': title}, do_follow=True,
|
||||||
**self.upload_data(filename))
|
**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
|
assert 'mediagoblin/user_pages/user.html' in context
|
||||||
# Make sure the media view is at least reachable, logged in...
|
# 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(' ', '-'))
|
title.lower().replace(' ', '-'))
|
||||||
self.test_app.get(url)
|
self.test_app.get(url)
|
||||||
# ... and logged out too.
|
# ... and logged out too.
|
||||||
@ -118,7 +128,7 @@ class TestSubmission:
|
|||||||
response, context = self.do_post({'title': u'Normal upload 3 (pdf)'},
|
response, context = self.do_post({'title': u'Normal upload 3 (pdf)'},
|
||||||
do_follow=True,
|
do_follow=True,
|
||||||
**self.upload_data(GOOD_PDF))
|
**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
|
assert 'mediagoblin/user_pages/user.html' in context
|
||||||
|
|
||||||
def check_media(self, request, find_data, count=None):
|
def check_media(self, request, find_data, count=None):
|
||||||
@ -164,7 +174,7 @@ class TestSubmission:
|
|||||||
# render and post to the edit page.
|
# render and post to the edit page.
|
||||||
edit_url = request.urlgen(
|
edit_url = request.urlgen(
|
||||||
'mediagoblin.edit.edit_media',
|
'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.get(edit_url)
|
||||||
self.test_app.post(edit_url,
|
self.test_app.post(edit_url,
|
||||||
{'title': u'Balanced Goblin',
|
{'title': u'Balanced Goblin',
|
||||||
@ -177,7 +187,7 @@ class TestSubmission:
|
|||||||
self.check_comments(request, media_id, 0)
|
self.check_comments(request, media_id, 0)
|
||||||
comment_url = request.urlgen(
|
comment_url = request.urlgen(
|
||||||
'mediagoblin.user_pages.media_post_comment',
|
'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'},
|
response = self.do_post({'comment_content': 'i love this test'},
|
||||||
url=comment_url, do_follow=True)[0]
|
url=comment_url, do_follow=True)[0]
|
||||||
self.check_comments(request, media_id, 1)
|
self.check_comments(request, media_id, 1)
|
||||||
@ -186,7 +196,7 @@ class TestSubmission:
|
|||||||
# ---------------------------------------------------
|
# ---------------------------------------------------
|
||||||
delete_url = request.urlgen(
|
delete_url = request.urlgen(
|
||||||
'mediagoblin.user_pages.media_confirm_delete',
|
'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
|
# Empty data means don't confirm
|
||||||
response = self.do_post({}, do_follow=True, url=delete_url)[0]
|
response = self.do_post({}, do_follow=True, url=delete_url)[0]
|
||||||
media = self.check_media(request, {'title': u'Balanced Goblin'}, 1)
|
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.
|
# they'll be caught as failures during the processing step.
|
||||||
response, context = self.do_post({'title': title}, do_follow=True,
|
response, context = self.do_post({'title': title}, do_follow=True,
|
||||||
**self.upload_data(filename))
|
**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()
|
entry = mg_globals.database.MediaEntry.query.filter_by(title=title).first()
|
||||||
assert entry.state == 'failed'
|
assert entry.state == 'failed'
|
||||||
assert entry.fail_error == u'mediagoblin.processing:BadMediaFail'
|
assert entry.fail_error == u'mediagoblin.processing:BadMediaFail'
|
||||||
|
@ -25,7 +25,7 @@ from webtest import TestApp
|
|||||||
|
|
||||||
from mediagoblin import mg_globals
|
from mediagoblin import mg_globals
|
||||||
from mediagoblin.db.models import User, MediaEntry, Collection, MediaComment, \
|
from mediagoblin.db.models import User, MediaEntry, Collection, MediaComment, \
|
||||||
CommentSubscription, CommentNotification, Privilege
|
CommentSubscription, CommentNotification, Privilege, CommentReport
|
||||||
from mediagoblin.tools import testing
|
from mediagoblin.tools import testing
|
||||||
from mediagoblin.init.config import read_mediagoblin_config
|
from mediagoblin.init.config import read_mediagoblin_config
|
||||||
from mediagoblin.db.base import Session
|
from mediagoblin.db.base import Session
|
||||||
@ -33,6 +33,8 @@ from mediagoblin.meddleware import BaseMeddleware
|
|||||||
from mediagoblin.auth import gen_password_hash
|
from mediagoblin.auth import gen_password_hash
|
||||||
from mediagoblin.gmg_commands.dbupdate import run_dbupdate
|
from mediagoblin.gmg_commands.dbupdate import run_dbupdate
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
MEDIAGOBLIN_TEST_DB_NAME = u'__mediagoblin_tests__'
|
MEDIAGOBLIN_TEST_DB_NAME = u'__mediagoblin_tests__'
|
||||||
TEST_SERVER_CONFIG = pkg_resources.resource_filename(
|
TEST_SERVER_CONFIG = pkg_resources.resource_filename(
|
||||||
@ -312,3 +314,33 @@ def fixture_add_comment(author=None, media_entry=None, comment=None):
|
|||||||
|
|
||||||
return comment
|
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
|
||||||
|
@ -52,7 +52,8 @@ def render_400(request, err_msg=None):
|
|||||||
_ = pass_to_ugettext
|
_ = pass_to_ugettext
|
||||||
title = _("Bad Request")
|
title = _("Bad Request")
|
||||||
if err_msg is None:
|
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)
|
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"
|
and the reason why they have been banned"
|
||||||
"""
|
"""
|
||||||
user_ban = UserBan.query.get(request.user.id)
|
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()
|
user_ban.delete()
|
||||||
redirect(request,
|
return redirect(request,
|
||||||
'index')
|
'index')
|
||||||
return render_to_response(request,
|
return render_to_response(request,
|
||||||
'mediagoblin/banned.html',
|
'mediagoblin/banned.html',
|
||||||
@ -141,7 +144,7 @@ def json_response(serializable, _disable_cors=False, *args, **kw):
|
|||||||
Any extra arguments and keyword arguments are passed to the
|
Any extra arguments and keyword arguments are passed to the
|
||||||
Response.__init__ method.
|
Response.__init__ method.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
response = wz_Response(json.dumps(serializable), *args, content_type='application/json', **kw)
|
response = wz_Response(json.dumps(serializable), *args, content_type='application/json', **kw)
|
||||||
|
|
||||||
if not _disable_cors:
|
if not _disable_cors:
|
||||||
|
@ -19,7 +19,7 @@ from mediagoblin.tools.template import render_template
|
|||||||
from mediagoblin.tools.translate import pass_to_ugettext as _
|
from mediagoblin.tools.translate import pass_to_ugettext as _
|
||||||
from mediagoblin import mg_globals
|
from mediagoblin import mg_globals
|
||||||
from mediagoblin.db.base import Session
|
from mediagoblin.db.base import Session
|
||||||
from mediagoblin.db.models import (CollectionItem, MediaReport, CommentReport,
|
from mediagoblin.db.models import (CollectionItem, MediaReport, CommentReport,
|
||||||
MediaComment, MediaEntry)
|
MediaComment, MediaEntry)
|
||||||
from mediagoblin.user_pages import forms as user_forms
|
from mediagoblin.user_pages import forms as user_forms
|
||||||
|
|
||||||
@ -80,14 +80,14 @@ def add_media_to_collection(collection, media, note=None, commit=True):
|
|||||||
|
|
||||||
def build_report_object(report_form, media_entry=None, comment=None):
|
def build_report_object(report_form, media_entry=None, comment=None):
|
||||||
"""
|
"""
|
||||||
This function is used to convert a form object (from a User filing a
|
This function is used to convert a form object (from a User filing a
|
||||||
report) into either a MediaReport or CommentReport object.
|
report) into either a MediaReport or CommentReport object.
|
||||||
|
|
||||||
:param report_form should be a MediaReportForm or a CommentReportForm
|
:param report_form should be a MediaReportForm or a CommentReportForm
|
||||||
object
|
object
|
||||||
:param
|
:param
|
||||||
|
|
||||||
:returns either of MediaReport or a CommentReport object that has not been
|
:returns either of MediaReport or a CommentReport object that has not been
|
||||||
saved. In case of an improper form_dict, returns None
|
saved. In case of an improper form_dict, returns None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -162,6 +162,7 @@ def media_home(request, media, page, **kwargs):
|
|||||||
|
|
||||||
@get_media_entry_by_id
|
@get_media_entry_by_id
|
||||||
@require_active_login
|
@require_active_login
|
||||||
|
@user_has_privilege(u'commenter')
|
||||||
def media_post_comment(request, media):
|
def media_post_comment(request, media):
|
||||||
"""
|
"""
|
||||||
recieves POST from a MediaEntry() comment form, saves the comment.
|
recieves POST from a MediaEntry() comment form, saves the comment.
|
||||||
@ -651,13 +652,13 @@ def file_a_report(request, media, comment=None):
|
|||||||
'form':form}
|
'form':form}
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
report_table = build_report_object(form,
|
report_object = build_report_object(form,
|
||||||
media_entry=media,
|
media_entry=media,
|
||||||
comment=comment)
|
comment=comment)
|
||||||
|
|
||||||
# if the object was built successfully, report_table will not be None
|
# if the object was built successfully, report_table will not be None
|
||||||
if report_table:
|
if report_object:
|
||||||
report_table.save()
|
report_object.save()
|
||||||
return redirect(
|
return redirect(
|
||||||
request,
|
request,
|
||||||
'index')
|
'index')
|
||||||
@ -671,5 +672,5 @@ def file_a_report(request, media, comment=None):
|
|||||||
@require_active_login
|
@require_active_login
|
||||||
@get_user_media_entry
|
@get_user_media_entry
|
||||||
@get_media_comment_by_id
|
@get_media_comment_by_id
|
||||||
def file_a_comment_report(request, media, comment):
|
def file_a_comment_report(request, media, comment):
|
||||||
return file_a_report(request, comment=comment)
|
return file_a_report(request, comment=comment)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user