diff --git a/mediagoblin/db/migrations.py b/mediagoblin/db/migrations.py
index 972908be..e15b4ad3 100644
--- a/mediagoblin/db/migrations.py
+++ b/mediagoblin/db/migrations.py
@@ -410,7 +410,7 @@ class ArchivedReport_v0(ReportBase_v0):
__tablename__ = 'core__reports_archived'
__mapper_args__ = {'polymorphic_identity': 'archived_report'}
- id = Column('id',Integer, ForeignKey('core__reports.id'))
+ id = Column('id',Integer, ForeignKey('core__reports.id'), primary_key=True)
media_entry_id = Column(Integer, ForeignKey(MediaEntry.id))
comment_id = Column(Integer, ForeignKey(MediaComment.id))
resolver_id = Column(Integer, ForeignKey(User.id), nullable=False)
diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py
index 32d3135f..54b8f739 100644
--- a/mediagoblin/db/models.py
+++ b/mediagoblin/db/models.py
@@ -106,6 +106,16 @@ class User(Base, UserMixin):
super(User, self).delete(**kwargs)
_log.info('Deleted user "{0}" account'.format(self.username))
+ def has_privilege(self,*priv_names):
+ if len(priv_names) == 1:
+ priv = Privilege.query.filter(
+ Privilege.privilege_name==priv_names[0]).one()
+ return (priv in self.all_privileges)
+ elif len(priv_names) > 1:
+ return self.has_privilege(priv_names[0]) or \
+ self.has_privilege(*priv_names[1:])
+ return False
+
class MediaEntry(Base, MediaEntryMixin):
"""
diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py
index 79b582c9..d3a9647e 100644
--- a/mediagoblin/decorators.py
+++ b/mediagoblin/decorators.py
@@ -35,11 +35,11 @@ def require_active_login(controller):
@wraps(controller)
def new_controller_func(request, *args, **kwargs):
if request.user and \
- request.user.status == u'needs_email_verification':
+ not request.user.has_privilege(u'active'):
return redirect(
request, 'mediagoblin.user_pages.user_home',
user=request.user.username)
- elif not request.user or request.user.status != u'active':
+ elif not request.user or not request.user.has_privilege(u'active'):
next_url = urljoin(
request.urlgen('mediagoblin.auth.login',
qualified=True),
@@ -72,13 +72,9 @@ def user_has_privilege(privilege_name):
@wraps(controller)
def wrapper(request, *args, **kwargs):
user_id = request.user.id
- privileges_of_user = Privilege.query.filter(
- Privilege.all_users.any(
- User.id==user_id))
if UserBan.query.filter(UserBan.user_id==user_id).count():
return render_user_banned(request)
- elif not privileges_of_user.filter(
- Privilege.privilege_name==privilege_name).count():
+ elif not request.user.has_privilege(privilege_name):
raise Forbidden()
return controller(request, *args, **kwargs)
@@ -94,7 +90,7 @@ def user_may_delete_media(controller):
@wraps(controller)
def wrapper(request, *args, **kwargs):
uploader_id = kwargs['media'].uploader
- if not (request.user.is_admin or
+ if not (request.user.has_privilege(u'admin') or
request.user.id == uploader_id):
raise Forbidden()
@@ -111,7 +107,7 @@ def user_may_alter_collection(controller):
def wrapper(request, *args, **kwargs):
creator_id = request.db.User.query.filter_by(
username=request.matchdict['user']).first().id
- if not (request.user.is_admin or
+ if not (request.user.has_privilege(u'admin') or
request.user.id == creator_id):
raise Forbidden()
@@ -309,13 +305,8 @@ def require_admin_or_moderator_login(controller):
"""
@wraps(controller)
def new_controller_func(request, *args, **kwargs):
- admin_privilege = Privilege.query.filter(
- Privilege.privilege_name==u'admin').one()
- moderator_privilege = Privilege.query.filter(
- Privilege.privilege_name==u'moderator').one()
if request.user and \
- not admin_privilege in request.user.all_privileges and \
- not moderator_privilege in request.user.all_privileges:
+ not request.user.has_privilege(u'admin',u'moderator'):
raise Forbidden()
elif not request.user:
diff --git a/mediagoblin/edit/lib.py b/mediagoblin/edit/lib.py
index aab537a0..6acebc96 100644
--- a/mediagoblin/edit/lib.py
+++ b/mediagoblin/edit/lib.py
@@ -19,6 +19,6 @@ def may_edit_media(request, media):
"""Check, if the request's user may edit the media details"""
if media.uploader == request.user.id:
return True
- if request.user.is_admin:
+ if request.user.has_privilege(u'admin'):
return True
return False
diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py
index 6aa2acd9..c6c3c03e 100644
--- a/mediagoblin/edit/views.py
+++ b/mediagoblin/edit/views.py
@@ -83,7 +83,7 @@ def edit_media(request, media):
return redirect_obj(request, media)
- if request.user.is_admin \
+ if request.user.has_privilege(u'admin') \
and media.uploader != request.user.id \
and request.method != 'POST':
messages.add_message(
@@ -184,7 +184,7 @@ def legacy_edit_profile(request):
def edit_profile(request, url_user=None):
# admins may edit any user profile
if request.user.username != url_user.username:
- if not request.user.is_admin:
+ if not request.user.has_privilege(u'admin'):
raise Forbidden(_("You can only edit your own profile."))
# No need to warn again if admin just submitted an edited profile
@@ -326,7 +326,7 @@ def edit_collection(request, collection):
return redirect_obj(request, collection)
- if request.user.is_admin \
+ if request.user.has_privilege(u'admin') \
and collection.creator != request.user.id \
and request.method != 'POST':
messages.add_message(
diff --git a/mediagoblin/gmg_commands/users.py b/mediagoblin/gmg_commands/users.py
index 7e6fc5bc..0002daad 100644
--- a/mediagoblin/gmg_commands/users.py
+++ b/mediagoblin/gmg_commands/users.py
@@ -85,7 +85,6 @@ def makeadmin(args):
user = db.User.query.filter_by(
username=unicode(args.username.lower())).one()
if user:
- user.is_admin = True
user.all_privileges.append(
db.Privilege.query.filter(
db.Privilege.privilege_name==u'admin').one()
diff --git a/mediagoblin/meta/__init__.py b/mediagoblin/meta/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/mediagoblin/meta/routing.py b/mediagoblin/meta/routing.py
new file mode 100644
index 00000000..e61bc065
--- /dev/null
+++ b/mediagoblin/meta/routing.py
@@ -0,0 +1,27 @@
+# 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 .
+
+meta_routes = [
+ ('mediagoblin.meta.code_of_conduct',
+ '/coc/',
+ 'mediagoblin.meta.views:code_of_conduct'),
+ ('mediagoblin.meta.reports_panel',
+ '/reports/',
+ 'mediagoblin.meta.views:public_reports_panel'),
+ ('mediagoblin.meta.reports_detail',
+ '/reports/',
+ 'mediagoblin.meta.views:public_reports_details')
+]
diff --git a/mediagoblin/meta/views.py b/mediagoblin/meta/views.py
new file mode 100644
index 00000000..3df0688c
--- /dev/null
+++ b/mediagoblin/meta/views.py
@@ -0,0 +1,33 @@
+# 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 .
+
+from mediagoblin.tools.response import render_to_response
+
+
+def code_of_conduct(request):
+ return render_to_response(request,
+ 'mediagoblin/meta/code_of_conduct.html',
+ {})
+
+def public_reports_panel(request):
+ return render_to_response(request,
+ 'mediagoblin/meta/reports_panel.html',
+ {})
+
+def public_reports_details(request):
+ return render_to_response(request,
+ 'mediagoblin/meta/reports_details.html',
+ {})
diff --git a/mediagoblin/moderation/views.py b/mediagoblin/moderation/views.py
index 041cf5b3..d82eca7d 100644
--- a/mediagoblin/moderation/views.py
+++ b/mediagoblin/moderation/views.py
@@ -74,15 +74,12 @@ def moderation_users_detail(request):
ReportBase.discriminator=='archived_report').all()
privileges = Privilege.query
user_banned = UserBan.query.get(user.id)
- user_privileges = user_privileges_to_dictionary(user.id)
- requesting_user_privileges = user_privileges_to_dictionary(request.user.id)
return render_to_response(
request,
'mediagoblin/moderation/user.html',
{'user':user,
'privileges': privileges,
- 'requesting_user_privileges':requesting_user_privileges,
'reports':active_reports,
'user_banned':user_banned})
@@ -121,7 +118,10 @@ def moderation_reports_detail(request):
for s in report.reported_user.all_privileges
]
- if request.method == "POST" and form.validate():
+ if request.method == "POST" and form.validate() and not (
+ not request.user.has_privilege(u'admin') and
+ report.reported_user.has_privilege(u'admin')):
+
user = User.query.get(form.targeted_user.data)
return take_punitive_actions(request, form, report, user)
diff --git a/mediagoblin/routing.py b/mediagoblin/routing.py
index c9377ad4..9686d103 100644
--- a/mediagoblin/routing.py
+++ b/mediagoblin/routing.py
@@ -20,6 +20,7 @@ from mediagoblin.tools.routing import add_route, mount, url_map
from mediagoblin.tools.pluginapi import PluginManager
from mediagoblin.moderation.routing import moderation_routes
from mediagoblin.auth.routing import auth_routes
+from mediagoblin.meta.routing import meta_routes
_log = logging.getLogger(__name__)
@@ -29,6 +30,7 @@ def get_url_map():
add_route('index', '/', 'mediagoblin.views:root_view')
mount('/auth', auth_routes)
mount('/mod', moderation_routes)
+ mount('/meta', meta_routes)
import mediagoblin.submit.routing
import mediagoblin.user_pages.routing
@@ -37,6 +39,7 @@ def get_url_map():
import mediagoblin.listings.routing
import mediagoblin.notifications.routing
+
for route in PluginManager().get_routes():
add_route(*route)
diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css
index 338828d2..1293086d 100644
--- a/mediagoblin/static/css/base.css
+++ b/mediagoblin/static/css/base.css
@@ -220,6 +220,7 @@ footer {
color: #283F35;
}
+
.button_form {
min-width: 99px;
margin: 10px 0px 10px 15px;
@@ -615,7 +616,7 @@ table.media_panel th {
text-align: left;
}
-/* admin panels */
+/* moderator panels */
table.admin_panel {
width: 100%
@@ -655,6 +656,21 @@ table td.user_without_privilege {
margin-left: 10px;
}
+/* code of conduct */
+
+#code_of_conduct_list {
+ margin-left:25px;
+ margin-bottom: 10px;
+}
+#code_of_conduct_list li {
+ margin-top:5px;
+}
+ol.nested_sublist{
+ margin: 5px 0 10px 25px;
+ font-size:80%;
+}
+
+
/* ASCII art and code */
@font-face {
diff --git a/mediagoblin/templates/mediagoblin/base.html b/mediagoblin/templates/mediagoblin/base.html
index 31f0f0c3..6eaad70b 100644
--- a/mediagoblin/templates/mediagoblin/base.html
+++ b/mediagoblin/templates/mediagoblin/base.html
@@ -109,9 +109,9 @@
{%- trans %}Create new collection{% endtrans -%}
- {% if request.user.is_admin %}
+ {% if request.user.has_privilege('admin','moderator') %}
- Admin powers:
+ Moderation powers:
{%- trans %}Media processing panel{% endtrans -%}
diff --git a/mediagoblin/templates/mediagoblin/meta/code_of_conduct.html b/mediagoblin/templates/mediagoblin/meta/code_of_conduct.html
new file mode 100644
index 00000000..e8233ad3
--- /dev/null
+++ b/mediagoblin/templates/mediagoblin/meta/code_of_conduct.html
@@ -0,0 +1,46 @@
+{#
+# 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 .
+#}
+{% extends "mediagoblin/base.html" %}
+
+{% block title %}
+ Code of Conduct
+{% endblock %}
+
+{% block mediagoblin_content -%}
+
{% trans %}Code of Conduct for this Website{% endtrans %}
+
+{# Suggested layout for this page:
+
+
Item #1
+
+ Item #2
+
+
Sub-Item #1
+
Sub-Item #2
+
+ Sub-Item #3
+
+
Sub-Subitem #1
+
+
+
+
+
Item #3
+
+#}
+{% endblock -%}
diff --git a/mediagoblin/templates/mediagoblin/meta/reports_details.html b/mediagoblin/templates/mediagoblin/meta/reports_details.html
new file mode 100644
index 00000000..6fa5ae59
--- /dev/null
+++ b/mediagoblin/templates/mediagoblin/meta/reports_details.html
@@ -0,0 +1,17 @@
+{#
+# 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 .
+#}
diff --git a/mediagoblin/templates/mediagoblin/meta/reports_panel.html b/mediagoblin/templates/mediagoblin/meta/reports_panel.html
new file mode 100644
index 00000000..6fa5ae59
--- /dev/null
+++ b/mediagoblin/templates/mediagoblin/meta/reports_panel.html
@@ -0,0 +1,17 @@
+{#
+# 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 .
+#}
diff --git a/mediagoblin/templates/mediagoblin/moderation/report.html b/mediagoblin/templates/mediagoblin/moderation/report.html
index b912c712..04788f05 100644
--- a/mediagoblin/templates/mediagoblin/moderation/report.html
+++ b/mediagoblin/templates/mediagoblin/moderation/report.html
@@ -122,7 +122,7 @@
{{ report.report_content }}
- {% if not report.is_archived_report() %}
+ {% if not report.is_archived_report() and not (report.reported_user.has_privilege('admin') and not request.user.has_privilege('admin')) %}