from werkzeug.exceptions import Forbidden
from mediagoblin.db.models import MediaEntry, User, MediaComment, CommentReport, ReportBase
-from mediagoblin.decorators import require_active_login
+from mediagoblin.decorators import require_admin_login
from mediagoblin.tools.response import render_to_response
-@require_active_login
+@require_admin_login
def admin_processing_panel(request):
'''
- Show the global processing panel for this instance
+ Show the global media processing panel for this instance
'''
- # TODO: Why not a "require_admin_login" decorator throwing a 403 exception?
- if not request.user.is_admin:
- raise Forbidden()
-
processing_entries = MediaEntry.query.filter_by(state = u'processing').\
order_by(MediaEntry.created.desc())
'failed_entries': failed_entries,
'processed_entries': processed_entries})
-@require_active_login
+@require_admin_login
def admin_users_panel(request):
'''
- Show the global processing panel for this instance
+ Show the global panel for monitoring users in this instance
'''
- # TODO: Why not a "require_admin_login" decorator throwing a 403 exception?
- if not request.user.is_admin:
- raise Forbidden()
-
user_list = User.query
# Render to response
'mediagoblin/admin/user.html',
{'user_list': user_list})
-@require_active_login
+@require_admin_login
def admin_reports_panel(request):
'''
- Show the global processing panel for this instance
+ Show the global panel for monitoring reports filed against comments or
+ media entries for this instance.
'''
- # TODO: Why not a "require_admin_login" decorator throwing a 403 exception?
- if not request.user.is_admin:
- raise Forbidden()
-
- report_list = ReportBase.query.filter(ReportBase.resolved==None).order_by(ReportBase.created.desc()).limit(10)
- closed_report_list = ReportBase.query.filter(ReportBase.resolved!=None).order_by(ReportBase.created.desc()).limit(10)
+ report_list = ReportBase.query.filter(
+ ReportBase.resolved==None).order_by(
+ ReportBase.created.desc()).limit(10)
+ closed_report_list = ReportBase.query.filter(
+ ReportBase.resolved!=None).order_by(
+ ReportBase.created.desc()).limit(10)
# Render to response
return render_to_response(
self.session.bind,
tables=[model.__table__ for model in self.models])
+ def populate_table_foundations(self):
+ """
+ Create the table foundations (default rows) as layed out in FOUNDATIONS
+ in mediagoblin.db.models
+ """
+ from mediagoblin.db.models import FOUNDATIONS as MAIN_FOUNDATIONS
+ for Model in MAIN_FOUNDATIONS.keys():
+ for parameters in MAIN_FOUNDATIONS[Model]:
+ row = Model(*parameters)
+ row.save()
+
def create_new_migration_record(self):
"""
Create a new migration record for this migration set
self.init_tables()
# auto-set at latest migration number
- self.create_new_migration_record()
-
+ self.create_new_migration_record()
+ if self.name==u'__main__':
+ self.populate_table_foundations()
+
self.printer(u"done.\n")
self.set_current_migration()
return u'inited'
__tablename__ = 'core__reports_on_media'
__mapper_args__ = {'polymorphic_identity': 'media_report'}
- id = Column('id',Integer, ForeignKey('core__reports.id'),
- primary_key=True)
+ id = Column(
+ 'id',
+ Integer,
+ ForeignKey('core__reports.id'),
+ primary_key=True)
media_entry_id = Column(Integer, ForeignKey(MediaEntry.id), nullable=False)
-@RegisterMigration(11, MIGRATIONS)
-def create_report_tables(db):
- ReportBase_v0.__table__.create(db.bind)
- CommentReport_v0.__table__.create(db.bind)
- MediaReport_v0.__table__.create(db.bind)
- db.commit()
class UserBan_v0(declarative_base()):
__tablename__ = 'core__user_bans'
class Group_v0(declarative_base()):
__tablename__ = 'core__groups'
- id = Column(Integer, nullable=False, primary_key=True)
+ id = Column(Integer, nullable=False, primary_key=True, unique=True)
group_name = Column(Unicode, nullable=False)
class GroupUserAssociation_v0(declarative_base()):
__tablename__ = 'core__group_user_associations'
- group_id = Column('core__group_id', Integer, ForeignKey(User.id), primary_key=True)
- user_id = Column('core__user_id', Integer, ForeignKey(Group.id), primary_key=True)
+ group_id = Column(
+ 'core__group_id',
+ Integer,
+ ForeignKey(User.id),
+ primary_key=True)
+ user_id = Column(
+ 'core__user_id',
+ Integer,
+ ForeignKey(Group.id),
+ primary_key=True)
-
-
-@RegisterMigration(12, MIGRATIONS)
-def create_banned_and_group_tables(db):
+@RegisterMigration(11, MIGRATIONS)
+def create_moderation_tables(db):
+ ReportBase_v0.__table__.create(db.bind)
+ CommentReport_v0.__table__.create(db.bind)
+ MediaReport_v0.__table__.create(db.bind)
UserBan_v0.__table__.create(db.bind)
Group_v0.__table__.create(db.bind)
GroupUserAssociation_v0.__table__.create(db.bind)
db.commit()
-
__tablename__ = 'core__reports'
id = Column(Integer, primary_key=True)
reporter_id = Column(Integer, ForeignKey(User.id), nullable=False)
- reporter = relationship(User, backref=backref("reports_filed_by",
- lazy="dynamic",
- cascade="all, delete-orphan"))
+ reporter = relationship(
+ User,
+ backref=backref("reports_filed_by",
+ lazy="dynamic",
+ cascade="all, delete-orphan"))
report_content = Column(UnicodeText)
- created = Column(DateTime, nullable=False, default=datetime.datetime.now())
+ created = Column(DateTime, nullable=False, default=datetime.datetime.now())
resolved = Column(DateTime)
discriminator = Column('type', Unicode(50))
__mapper_args__ = {'polymorphic_on': discriminator}
id = Column('id',Integer, ForeignKey('core__reports.id'),
primary_key=True)
comment_id = Column(Integer, ForeignKey(MediaComment.id), nullable=False)
- comment = relationship(MediaComment, backref=backref("reports_filed_on",
- lazy="dynamic",
- cascade="all, delete-orphan"))
+ comment = relationship(
+ MediaComment, backref=backref("reports_filed_on",
+ lazy="dynamic",
+ cascade="all, delete-orphan"))
class MediaReport(ReportBase):
"""
id = Column('id',Integer, ForeignKey('core__reports.id'),
primary_key=True)
media_entry_id = Column(Integer, ForeignKey(MediaEntry.id), nullable=False)
- media_entry = relationship(MediaEntry, backref=backref("reports_filed_on",
- lazy="dynamic",
- cascade="all, delete-orphan"))
+ media_entry = relationship(
+ MediaEntry,
+ backref=backref("reports_filed_on",
+ lazy="dynamic",
+ cascade="all, delete-orphan"))
class UserBan(Base):
"""
- 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. 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 lifted
- :param user_id Holds the id of the user this object is attached to.
- This should be a one-to-one relationship.
- :param expiration_date Holds the date that the ban will be lifted. If this
- is null, the ban is permanent unless a moderator
- manually lifts it.
+ 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.
+ 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
+ lifted
+
+ :param user_id Holds the id of the user this object is
+ attached to. This is a one-to-one
+ relationship.
+ :param expiration_date Holds the date that the ban will be lifted.
+ If this is null, the ban is permanent
+ unless a moderator manually lifts it.
:param reason Holds the reason why the user was banned.
"""
__tablename__ = 'core__user_bans'
- user_id = Column('id',Integer, ForeignKey(User.id), nullable=False,
- primary_key=True)
+ user_id = Column(Integer, ForeignKey(User.id), nullable=False,
+ primary_key=True)
expiration_date = Column(DateTime)
reason = Column(UnicodeText, nullable=False)
__tablename__ = 'core__groups'
id = Column(Integer, nullable=False, primary_key=True)
- group_name = Column(Unicode, nullable=False)
- all_users = relationship(User, backref='all_groups', secondary="core__group_user_associations")
+ group_name = Column(Unicode, nullable=False, unique=True)
+ all_users = relationship(
+ User,
+ backref='all_groups',
+ secondary="core__group_user_associations")
+
+ def __init__(self, group_name):
+ self.group_name = group_name
def __repr__(self):
return "<Group %s>" % (self.group_name)
class GroupUserAssociation(Base):
__tablename__ = 'core__group_user_associations'
- group_id = Column('core__group_id', Integer, ForeignKey(User.id), primary_key=True)
- user_id = Column('core__user_id', Integer, ForeignKey(Group.id), primary_key=True)
+ group_id = Column(
+ 'core__group_id',
+ Integer,
+ ForeignKey(User.id),
+ primary_key=True)
+ user_id = Column(
+ 'core__user_id',
+ Integer,
+ ForeignKey(Group.id),
+ primary_key=True)
+group_foundations = [[u'admin'], [u'moderator'], [u'commenter'], [u'uploader'],[u'reporter'],[u'active']]
MODELS = [
- User, MediaEntry, Tag, MediaTag, MediaComment, Collection, CollectionItem, MediaFile, FileKeynames,
- MediaAttachmentFile, ProcessingMetaData, CommentReport, MediaReport, UserBan, Group, GroupUserAssociation]
+ User, MediaEntry, Tag, MediaTag, MediaComment, Collection, CollectionItem,
+ MediaFile, FileKeynames, MediaAttachmentFile, ProcessingMetaData, ReportBase,
+ CommentReport, MediaReport, UserBan, Group, GroupUserAssociation]
+
+# Foundations are the default rows that are created immediately after the tables are initialized. Each entry to
+# this dictionary should be in the format of
+# ModelObject:List of Rows
+# (Each Row must be a list of parameters that can create and instance of the ModelObject)
+#
+FOUNDATIONS = {Group:group_foundations}
######################################################
# Special, migrations-tracking table
from werkzeug.urls import url_quote
from mediagoblin import mg_globals as mgg
-from mediagoblin.db.models import MediaEntry, User, MediaComment
+from mediagoblin.db.models import MediaEntry, User, MediaComment, Group
from mediagoblin.tools.response import redirect, render_404
return wrapper
+def user_in_group(group_name):
+#TODO handle possible errors correctly
+ def user_in_group_decorator(controller):
+ @wraps(controller)
+
+ def wrapper(request, *args, **kwargs):
+ user_id = request.user.id
+ group = Group.query.filter(
+ Group.group_name==group_name).first()
+ if not (group.query.filter(
+ Group.all_users.any(
+ User.id==user_id)).count()):
+
+ raise Forbidden()
+
+ return controller(request, *args, **kwargs)
+
+ return wrapper
+ return user_in_group_decorator
+
def user_may_delete_media(controller):
"""
return func(*args, workbench=workbench, **kwargs)
return new_func
+
+def require_admin_login(controller):
+ """
+ Require an login from an administrator.
+ """
+ @wraps(controller)
+ def new_controller_func(request, *args, **kwargs):
+ if request.user and \
+ not request.user.is_admin:
+ raise Forbidden()
+ elif not request.user:
+ next_url = urljoin(
+ request.urlgen('mediagoblin.auth.login',
+ qualified=True),
+ request.url)
+
+ return redirect(request, 'mediagoblin.auth.login',
+ next=next_url)
+
+ return controller(request, *args, **kwargs)
+
+ return new_controller_func
+
report_reason = wtforms.TextAreaField('Reason for Reporting')
media_entry_id = wtforms.IntegerField()
reporter_id = wtforms.IntegerField()
-
-class ReportForm(wtforms.Form):
- report_reason = wtforms.TextAreaField('Reason for Reporting')
- media_entry_id = wtforms.IntegerField()
- reporter_id = wtforms.IntegerField()
- comment_id = wtforms.IntegerField()
def build_report_form(form_dict):
"""
- :param form_dict should be an ImmutableMultiDict object which is what is
- returned from 'request.form.' The Object should have valid keys
- matching the fields in either MediaReportForm or CommentReportForm
+ This function is used to convert a form dictionary (from a User filing a
+ report) into either a MediaReport or CommentReport object.
- :returns either of MediaReport or a CommentReport object that has not been saved.
- In case of an improper form_dict, returns None
+ :param form_dict should be an ImmutableMultiDict object as is returned from
+ 'request.form.' The Object should have valid keys matching the fields
+ in either MediaReportForm or CommentReportForm
+
+ :returns either of MediaReport or a CommentReport object that has not been
+ saved. In case of an improper form_dict, returns None
"""
if 'comment_id' in form_dict.keys():
report_form = user_forms.CommentReportForm(form_dict)
report_form = user_forms.MediaReportForm(form_dict)
else:
return None
+
if report_form.validate() and 'comment_id' in form_dict.keys():
report_model = CommentReport()
report_model.comment_id = report_form.comment_id.data
report_model.media_entry_id = report_form.media_entry_id.data
else:
return None
+
report_model.report_content = report_form.report_reason.data or u''
report_model.reporter_id = report_form.reporter_id.data
return report_model
from mediagoblin import messages, mg_globals
from mediagoblin.db.models import (MediaEntry, MediaTag, Collection,
CollectionItem, User, MediaComment,
- CommentReport, MediaReport)
+ CommentReport, MediaReport, Group)
from mediagoblin.tools.response import render_to_response, render_404, \
redirect, redirect_obj
from mediagoblin.tools.translate import pass_to_ugettext as _
add_media_to_collection)
from mediagoblin.decorators import (uses_pagination, get_user_media_entry,
- get_media_entry_by_id,
+ get_media_entry_by_id, user_in_group,
require_active_login, user_may_delete_media, user_may_alter_collection,
get_user_collection, get_user_collection_item, active_user_from_url,
get_media_comment_by_id)
@require_active_login
@get_user_media_entry
-def file_a_report(request, media, comment=None):
+@user_in_group(u'reporter')
+def file_a_report(request, media, comment=None, required_group=1):
if request.method == "POST":
report_form = build_report_form(request.form)
report_form.save()
+
return redirect(
- request,
- 'index')
+ request,
+ 'index')
+
if comment is not None:
context = {'media': media,
- 'comment':comment}
+ 'comment':comment}
else:
context = {'media': media}
+
return render_to_response(
- request,
- 'mediagoblin/user_pages/report.html',
- context)
+ request,
+ 'mediagoblin/user_pages/report.html',
+ context)
@require_active_login
@get_user_media_entry