user = User.query.filter_by(id=int(token)).first()
- if user and user.email_verified is False:
- user.status = u'active'
- user.email_verified = True
+ if user and user.has_privilege(u'active') is False:
user.verification_key = None
user.all_privileges.append(
Privilege.query.filter(
return redirect(request, 'mediagoblin.auth.login')
- if request.user.email_verified:
+ if request.user.has_privilege(u'active'):
messages.add_message(
request,
messages.ERROR,
success_message=_("An email has been sent with instructions "
"on how to change your password.")
- if user and not(user.email_verified and user.status == 'active'):
+ if user and not(user.has_privilege(u'active')):
# Don't send reminder because user is inactive or has no verified email
messages.add_message(request,
messages.WARNING,
return redirect(
request, 'index')
- # check if user active and has email verified
- if user.email_verified and user.status == 'active':
+ # check if user active
+ if user.has_privilege(u'active'):
cp_form = auth_forms.ChangePassForm(formdata_vars)
'mediagoblin/auth/change_fp.html',
{'cp_form': cp_form,})
- if not user.email_verified:
+ if not user.has_privilege(u'active'):
messages.add_message(
request, messages.ERROR,
_('You need to verify your email before you can reset your'
' password.'))
- if not user.status == 'active':
+ if not user.has_privilege(u'active'):
messages.add_message(
request, messages.ERROR,
_('You are no longer an active user. Please contact the system'
from mediagoblin.db.extratypes import JSONEncoded
from mediagoblin.db.migration_tools import RegisterMigration, inspect_table
from mediagoblin.db.models import (MediaEntry, Collection, User,
- MediaComment, Privilege, ReportBase)
+ MediaComment, Privilege, ReportBase,
+ FOUNDATIONS)
MIGRATIONS = {}
UserBan_v0.__table__.create(db.bind)
Privilege_v0.__table__.create(db.bind)
PrivilegeUserAssociation_v0.__table__.create(db.bind)
+
db.commit()
+ for parameters in FOUNDATIONS[Privilege]:
+ p = Privilege(**parameters)
+ p.save()
+
+@RegisterMigration(16, MIGRATIONS)
+def update_user_privilege_columns(db):
+ metadata = MetaData(bind=db.bind)
+ default_privileges = Privilege.query.filter(
+ Privilege.privilege_name !=u'admin').filter(
+ Privilege.privilege_name !=u'moderator').filter(
+ Privilege.privilege_name !=u'active').all()
+ admin_privilege = Privilege.query.filter(
+ Privilege.privilege_name ==u'admin').first()
+ active_privilege = Privilege.query.filter(
+ Privilege.privilege_name ==u'active').first()
+ for inactive_user in User.query.filter(
+ User.status!=u'active').filter(
+ User.is_admin==False).all():
+
+ inactive_user.all_privileges = default_privileges
+ inactive_user.save()
+ for user in User.query.filter(
+ User.status==u'active').filter(
+ User.is_admin==False).all():
+
+ user.all_privileges = default_privileges + [active_privilege]
+ user.save()
+ for admin_user in User.query.filter(
+ User.is_admin==True).all():
+
+ admin_user.all_privileges = default_privileges + [
+ admin_privilege, active_privilege]
+ admin_user.save()
return '<{0} #{1} {2} {3} "{4}">'.format(
self.__class__.__name__,
self.id,
- 'verified' if self.email_verified else 'non-verified',
- 'admin' if self.is_admin else 'user',
+ 'verified' if self.has_privilege(u'active') else 'non-verified',
+ 'admin' if self.has_privilege(u'admin') else 'user',
self.username)
def delete(self, **kwargs):
entry.username = unicode(args.username.lower())
entry.email = unicode(args.email)
entry.pw_hash = auth.gen_password_hash(args.password)
- entry.status = u'active'
- entry.email_verified = True
default_privileges = [
db.Privilege.query.filter(
db.Privilege.privilege_name==u'commenter').one(),
# along with this program. If not, see <http://www.gnu.org/licenses/>.
meta_routes = [
- ('mediagoblin.meta.code_of_conduct',
- '/coc/',
- 'mediagoblin.meta.views:code_of_conduct'),
+ ('mediagoblin.meta.terms_of_service',
+ '/tos/',
+ 'mediagoblin.meta.views:terms_of_service'),
('mediagoblin.meta.reports_panel',
'/reports/',
'mediagoblin.meta.views:public_reports_panel'),
from mediagoblin.tools.response import render_to_response
-def code_of_conduct(request):
+def terms_of_service(request):
return render_to_response(request,
- 'mediagoblin/meta/code_of_conduct.html',
+ 'mediagoblin/meta/terms_of_service.html',
{})
def public_reports_panel(request):
margin-bottom: 10px;
}
#code_of_conduct_list li {
- margin-top:5px;
+ margin:5px 0 15px 25px;
}
-ol.nested_sublist{
+.nested_sublist {
margin: 5px 0 10px 25px;
font-size:80%;
}
-
+.nested_sublist li {
+ margin-bottom: 10px;
+}
/* ASCII art and code */
{% block mediagoblin_header_title %}{% endblock %}
<div class="header_right">
{%- if request.user %}
- {% if request.user and request.user.status == 'active' and not request.user.is_banned() %}
+ {% if request.user and request.user.has_privilege('active') and not request.user.is_banned() %}
{% set notification_count = get_notification_count(request.user.id) %}
{% if notification_count %}
{% endif %}
<a href="javascript:;" class="button_action header_dropdown_down">▼</a>
<a href="javascript:;" class="button_action header_dropdown_up">▲</a>
- {% elif request.user and request.user.status == "needs_email_verification" %}
+ {% elif request.user and not request.user.has_privilege('active') %}
{# the following link should only appear when verification is needed #}
<a href="{{ request.urlgen('mediagoblin.user_pages.user_home',
user=request.user.username) }}"
"javascript:;"
{% endif %}
>{% trans %}log out{% endtrans %}</a>
+ {% elif request.user and request.user.is_banned() %}
+ <a id="logout" href=
+ {% if persona is not defined %}
+ "{{ request.urlgen('mediagoblin.auth.logout') }}"
+ {% else %}
+ "javascript:;"
+ {% endif %}
+ >{% trans %}log out{% endtrans %}</a>
{% endif %}
{%- elif auth %}
<a href=
{%- endif %}
</div>
<div class="clear"></div>
- {% if request.user and request.user.status == 'active' %}
+ {% if request.user and request.user.has_privilege('active') %}
<div class="header_dropdown">
<p>
<span class="dropdown_title">
+{#
+# 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/>.
+#}
+{% extends "mediagoblin/base.html" %}
+
+{% block title %}
+ Terms of Service
+{% endblock %}
+
+{% block mediagoblin_content -%}
<h2>The gist</h2>
<h2>Terms of Service</h2>
Please read this Agreement carefully before accessing or using the Website. By accessing or using any part of the web site, you agree to become bound by the terms and conditions of this agreement. If you do not agree to all the terms and conditions of this agreement, then you may not access the Website or use any services. If these terms and conditions are considered an offer by Operator, acceptance is expressly limited to these terms. The Website is available only to individuals who are at least 13 years old.
-<ol>
- <li>Your {{ app_config['html_title'] }} Account and Site. If you create a
+<ol id="code_of_conduct_list">
+ <li><strong>Your {{ app_config['html_title'] }} Account and Site.</strong> If you create a
notice stream on the Website, you are responsible for maintaining the
security of your account and notice stream, and you are fully responsible
for all activities that occur under the account and any other actions taken
including any damages of any kind incurred as a result of such acts or
omissions.
</li>
- <li>Responsibility of Contributors. If you operate a notice stream, comment
+ <li><strong>Responsibility of Contributors.</strong> If you operate a notice stream, comment
on a notice stream, post material to the Website, post links on the
Website, or otherwise make (or allow any third party to make) material
available by means of the Website (any such material, “Content”), You are
Content. That is the case regardless of whether the Content in question
constitutes text, graphics, an audio file, or computer software. By making
Content available, you represent and warrant that:
- <ul>
+ <ul class="nested_sublist">
<li>the downloading, copying and use of the Content will not infringe
the proprietary rights, including but not limited to the copyright,
patent, trademark or trade secret rights, of any third party;
(ii) terminate or deny access to and use of the Website to any individual
or entity for any reason, in Operator’s sole discretion.
</li>
- <li>Responsibility of Website Visitors. Operator has not reviewed, and cannot
+ <li><strong>Responsibility of Website Visitors.</strong> Operator has not reviewed, and cannot
review, all of the material, including computer software, posted to the
Website, and cannot therefore be responsible for that material’s content,
use or effects. By operating the Website, Operator does not represent or
visitors of the Website, or from any downloading by those visitors of
content there posted.
</li>
- <li>Content Posted on Other Websites. We have not reviewed, and cannot
+ <li><strong>Content Posted on Other Websites.</strong> We have not reviewed, and cannot
review, all of the material, including computer software, made available
through the websites and webpages to which {{ app_config['html_title'] }}
links, and that link to {{ app_config['html_title'] }}. Operator does not
disclaims any responsibility for any harm resulting from your use of
external websites and webpages.
</li>
- <li>Copyright Infringement and DMCA Policy. As Operator asks others to
+ <li><strong>Copyright Infringement and DMCA Policy.</strong> As Operator asks others to
respect its intellectual property rights, it respects the intellectual
property rights of others. If you believe that material located on or
linked to by {{ app_config['html_title'] }} violates your copyright, you
the Website. In the case of such termination, Operator will have no
obligation to provide a refund of any amounts previously paid to Operator.
</li>
- <li>Intellectual Property. This Agreement does not transfer from Operator to
+ <li><strong>Intellectual Property.</strong> This Agreement does not transfer from Operator to
you any Operator or third party intellectual property, and all right,
title and interest in and to such property will remain (as between the
parties) solely with Operator. {{ app_config['html_title'] }}, the
Website grants you no right or license to reproduce or otherwise use any
Operator or third-party trademarks.
</li>
- <li>Changes. Operator reserves the right, at its sole discretion, to modify
+ <li><strong>Changes.</strong> Operator reserves the right, at its sole discretion, to modify
or replace any part of this Agreement. It is your responsibility to check
this Agreement periodically for changes. Your continued use of or access
to the Website following the posting of any changes to this Agreement
release of new tools and resources). Such new features and/or services
shall be subject to the terms and conditions of this Agreement.
</li>
- <li>Termination. Operator may terminate your access to all or any part of
+ <li><strong>Termination.</strong> Operator may terminate your access to all or any part of
the Website at any time, with or without cause, with or without notice,
effective immediately. If you wish to terminate this Agreement or your
{{ app_config['html_title'] }} account (if you have one), you may simply
including, without limitation, ownership provisions, warranty disclaimers,
indemnity and limitations of liability.
</li>
- <li>Disclaimer of Warranties. The Website is provided “as is”. Operator and
+ <li><strong>Disclaimer of Warranties.</strong> The Website is provided “as is”. Operator and
its suppliers and licensors hereby disclaim all warranties of any kind,
express or implied, including, without limitation, the warranties of
merchantability, fitness for a particular purpose and non-infringement.
understand that you download from, or otherwise obtain content or services
through, the Website at your own discretion and risk.
</li>
- <li>Limitation of Liability. In no event will Operator, or its suppliers or
+ <li><strong>Limitation of Liability.</strong> In no event will Operator, or its suppliers or
licensors, be liable with respect to any subject matter of this agreement
under any contract, negligence, strict liability or other legal or
equitable theory for: (i) any special, incidental or consequential damages;
reasonable control. The foregoing shall not apply to the extent prohibited
by applicable law.
</li>
- <li>General Representation and Warranty. You represent and warrant that (i)
+ <li><strong>General Representation and Warranty.</strong> You represent and warrant that (i)
your use of the Website will be in strict accordance with the Operator
Privacy Policy, with this Agreement and with all applicable laws and
regulations (including without limitation any local laws or regulations in
infringe or misappropriate the intellectual property rights of any third
party.
</li>
- <li>Indemnification. You agree to indemnify and hold harmless Operator, its
+ <li><strong>Indemnification.</strong> You agree to indemnify and hold harmless Operator, its
contractors, and its licensors, and their respective directors, officers,
employees and agents from and against any and all claims and expenses,
including attorneys’ fees, arising out of your use of the Website,
including but not limited to out of your violation this Agreement.
</li>
- <li>Miscellaneous. This Agreement constitutes the entire agreement between
+ <li><strong>Miscellaneous.</strong> This Agreement constitutes the entire agreement between
Operator and you concerning the subject matter hereof, and they may only
be modified by a written amendment signed by an authorized executive of
Operator, or by the posting by Operator of a revised version. If any part
rename "blog" to "notice stream", remove the choice-of-venue clause, and add
variables specific to instances of this software made by Control Yourself, Inc.
and made available under the terms of the same license.
+
+{% endblock -%}
{% if not user %}
<p>{% trans %}Sorry, no such user found.{% endtrans %}</p>
{# User exists, but needs verification #}
- {% elif user.status == "needs_email_verification" %}
+ {% elif not user.has_privilege('active') %}
<div class="form_box">
<h1>{% trans %}Email verification needed{% endtrans %}</h1>
<p>
</h1>
{% if request.user %}
- {% if request.user.status == 'active' %}
+ {% if request.user.has_privilege('active') %}
<p>
<a href="{{ request.urlgen('mediagoblin.submit.collection',
user=user.username) }}">
<p>{% trans %}Sorry, no such user found.{% endtrans %}</p>
{# User exists, but needs verification #}
- {% elif user.status == "needs_email_verification" %}
+ {% elif not user.status.has_privilege('active') %}
{% if user == request.user %}
{# this should only be visible when you are this user #}
<div class="form_box">
new_user = mg_globals.database.User.query.filter_by(
username=u'angrygirl').first()
assert new_user
- assert new_user.status == u'needs_email_verification'
- assert new_user.email_verified == False
## Make sure that the proper privileges are granted on registration
new_user = mg_globals.database.User.query.filter_by(
username=u'angrygirl').first()
assert new_user
- assert new_user.status == u'needs_email_verification'
- assert new_user.email_verified == False
## Verify the email activation works
template.clear_test_template_context()
new_user = mg_globals.database.User.query.filter_by(
username=u'angrygirl').first()
assert new_user
- assert new_user.status == u'active'
- assert new_user.email_verified == True
# Uniqueness checks
# -----------------
# Get user and detach from session
test_user = mg_globals.database.User.query.filter_by(
username=u'chris').first()
- test_user.email_verified = True
- test_user.status = u'active'
test_user.save()
test_user = mg_globals.database.User.query.filter_by(
username=u'chris').first()
user = User.query.filter_by(username=request.matchdict['user']).first()
if not user:
return render_404(request)
- elif user.status != u'active':
+ elif not user.has_privilege(u'active'):
return render_to_response(
request,
'mediagoblin/user_pages/user.html',
generates the atom feed with the newest images
"""
user = User.query.filter_by(
- username = request.matchdict['user'],
- status = u'active').first()
- if not user:
+ username = request.matchdict['user']).first()
+ if not user or not user.has_privilege(u'active'):
return render_404(request)
cursor = MediaEntry.query.filter_by(
generates the atom feed with the newest images from a collection
"""
user = User.query.filter_by(
- username = request.matchdict['user'],
- status = u'active').first()
- if not user:
+ username = request.matchdict['user']).first()
+ if not user or not user.has_privilege(u'active'):
return render_404(request)
collection = Collection.query.filter_by(