Skip to content

Commit

Permalink
Added separate column for user ban status in the user table. Also
Browse files Browse the repository at this point in the history
improved the unittests to not log out from the admin panel when traversing
the links.
  • Loading branch information
mitsuhiko committed Oct 4, 2009
1 parent 2bd34e0 commit e2f1e4f
Show file tree
Hide file tree
Showing 10 changed files with 29 additions and 21 deletions.
1 change: 1 addition & 0 deletions SCHEMA_CHANGES
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ Schema changes from first release to development version. This will
later be integrated into a proper update script: later be integrated into a proper update script:


alter table user_messages add column type varchar(10) after text; alter table user_messages add column type varchar(10) after text;
alter table users add column type boolean after is_admin;
2 changes: 1 addition & 1 deletion solace/_openid_auth.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def first_login(self, request):


form = OpenIDRegistrationForm() form = OpenIDRegistrationForm()
if request.method == 'POST' and form.validate(): if request.method == 'POST' and form.validate():
user = User(form['username'], form['email'], '!') user = User(form['username'], form['email'])
user.openid_logins.add(identity_url) user.openid_logins.add(identity_url)
self.after_register(request, user) self.after_register(request, user)
session.commit() session.commit()
Expand Down
3 changes: 3 additions & 0 deletions solace/default_settings.cfg
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ SMTP_USE_TLS = False
#: in the LANGUAGE_SECTIONS list. #: in the LANGUAGE_SECTIONS list.
DEFAULT_LANGUAGE = 'en' DEFAULT_LANGUAGE = 'en'


#: if a user is unbanned, should he pick a new password?
REQUIRE_NEW_PASSWORD_ON_UNBAN = False

#: the languages for which sections exist. Ideally we also have #: the languages for which sections exist. Ideally we also have
#: translations of the application for these languages, but if a #: translations of the application for these languages, but if a
#: language is missing in the UI it falls back to english. #: language is missing in the UI it falls back to english.
Expand Down
10 changes: 1 addition & 9 deletions solace/models.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -100,10 +100,6 @@ def active_in(self, locale):
return self.filter(User.id.in_(select([ua.user_id], return self.filter(User.id.in_(select([ua.user_id],
ua.locale == str(locale)))) ua.locale == str(locale))))


def banned(self):
"""Returns all the banned users."""
return self.filter_by(pw_hash=None)



class User(RemoteObject): class User(RemoteObject):
"""Represents a user on the system.""" """Represents a user on the system."""
Expand All @@ -124,6 +120,7 @@ def __init__(self, username, email, password=None, is_admin=False):
self.real_name = u'' self.real_name = u''
self.is_admin = is_admin self.is_admin = is_admin
self.is_active = True self.is_active = True
self.is_banned = False
self.last_login = None self.last_login = None
if password is not None: if password is not None:
self.set_password(password) self.set_password(password)
Expand Down Expand Up @@ -157,11 +154,6 @@ def is_moderator(self):
return self.is_admin or self.reputation >= \ return self.is_admin or self.reputation >= \
settings.REPUTATION_MAP['IS_MODERATOR'] settings.REPUTATION_MAP['IS_MODERATOR']


@property
def is_banned(self):
"""If the user does not have a password he's marked as banned."""
return self.pw_hash is None

@property @property
def display_name(self): def display_name(self):
return self.real_name or self.username return self.real_name or self.username
Expand Down
6 changes: 5 additions & 1 deletion solace/schema.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
# the email of the user. If an external auth system is used, the # the email of the user. If an external auth system is used, the
# login code should update that information automatically on login # login code should update that information automatically on login
Column('email', String(200), index=True), Column('email', String(200), index=True),
# the password hash. Probably only used for the builtin auth system. # the password hash. This might not be used by every auth system.
# the OpenID auth for example does not use it at all. But also
# external auth systems might not store the password here.
Column('pw_hash', String(60)), Column('pw_hash', String(60)),
# the realname of the user # the realname of the user
Column('real_name', String(200)), Column('real_name', String(200)),
Expand All @@ -46,6 +48,8 @@
Column('platin_badges', Integer, nullable=False), Column('platin_badges', Integer, nullable=False),
# true if the user is an administrator # true if the user is an administrator
Column('is_admin', Boolean, nullable=False), Column('is_admin', Boolean, nullable=False),
# true if the user is banned
Column('is_banned', Boolean, nullable=False),
# the date of the last login # the date of the last login
Column('last_login', DateTime), Column('last_login', DateTime),
# the user's activation key. If this is NULL, the user is already # the user's activation key. If this is NULL, the user is already
Expand Down
2 changes: 1 addition & 1 deletion solace/templates/admin/bans.html
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ <h3>{{ _('Banned Users') }}</h3>
<ul class="userlist"> <ul class="userlist">
{%- for user in banned_users %} {%- for user in banned_users %}
<li>{{ render_user(user, avatar_size=26) }} <li>{{ render_user(user, avatar_size=26) }}
<span class="action">[<a href="{{ url_for('admin.unban', user=user.username) <span class="action">[<a href="{{ url_for('admin.unban_user', user=user.username)
}}">{{ _('lift the ban') }}</a>]</span> }}">{{ _('lift the ban') }}</a>]</span>
{%- else %} {%- else %}
<li>{{ _('No users are currently banned.') }} <li>{{ _('No users are currently banned.') }}
Expand Down
7 changes: 5 additions & 2 deletions solace/templates/mails/user_unbanned.txt
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
Hi {{ user }}! Hi {{ user }}!


Your ban on {{ site }} was lifted. Your ban on {{ site }} was lifted.
{%- endtrans %}

{%- if settings.REQUIRE_NEW_PASSWORD_ON_UNBAN %}{% trans %}


In order to login again you have to follow the following In order to login again you have to follow the following
link and pick a new password: link and pick a new password:


{{ reset_url }} {{ reset_url }}{% endtrans %}{% endif %}


See you soon on {{ site }} {% trans site=settings.WEBSITE_TITLE %}See you soon on {{ site }}
{%- endtrans %}{% endblock %} {%- endtrans %}{% endblock %}
8 changes: 6 additions & 2 deletions solace/tests/link_check.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ def test_only_valid_links(self):
"""Make sure that all links are valid""" """Make sure that all links are valid"""
settings.LANGUAGE_SECTIONS = ['en'] settings.LANGUAGE_SECTIONS = ['en']
user = models.User('user1', 'user1@example.com', 'default') user = models.User('user1', 'user1@example.com', 'default')
user.active = True user.is_admin = True
banned_user = models.User('user2', 'user2@example.com', 'default')
banned_user.is_banned = True
topic = models.Topic('en', 'This is a test topic', 'Foobar', user) topic = models.Topic('en', 'This is a test topic', 'Foobar', user)
post1 = models.Post(topic, user, 'meh1') post1 = models.Post(topic, user, 'meh1')
post2 = models.Post(topic, user, 'meh2') post2 = models.Post(topic, user, 'meh2')
Expand All @@ -40,7 +42,9 @@ def visit(url):
if not url.startswith(BASE_URL) or url in visited_links: if not url.startswith(BASE_URL) or url in visited_links:
return return
visited_links.add(url) visited_links.add(url)
path = url.split('/', 3)[-1] path = '/' + url.split('/', 3)[-1]
if path.startswith('/logout?'):
return
response = self.client.get(path, follow_redirects=True) response = self.client.get(path, follow_redirects=True)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
for link in response.html.xpath('//a[@href]'): for link in response.html.xpath('//a[@href]'):
Expand Down
9 changes: 5 additions & 4 deletions solace/utils/admin.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
:copyright: (c) 2009 by Plurk Inc., see AUTHORS for more details. :copyright: (c) 2009 by Plurk Inc., see AUTHORS for more details.
:license: BSD, see LICENSE for more details. :license: BSD, see LICENSE for more details.
""" """
from solace import settings
from solace.i18n import _ from solace.i18n import _
from solace.application import url_for from solace.application import url_for
from solace.templating import render_template from solace.templating import render_template
Expand All @@ -22,7 +23,7 @@ def ban_user(user):
if user.is_banned: if user.is_banned:
return return


user.pw_hash = None user.is_banned = True
send_email(_(u'User account banned'), send_email(_(u'User account banned'),
render_template('mails/user_banned.txt', user=user), render_template('mails/user_banned.txt', user=user),
user.email) user.email)
Expand All @@ -37,9 +38,9 @@ def unban_user(user):
if not user.is_banned: if not user.is_banned:
return return


# special password value that will never validate but does not if settings.REQUIRE_NEW_PASSWORD_ON_UNBAN:
# trigger a "user is deativated". user.is_active = False
user.pw_hash = '!' user.is_banned = False
reset_url = url_for('core.reset_password', email=user.email, reset_url = url_for('core.reset_password', email=user.email,
key=user.password_reset_key, _external=True) key=user.password_reset_key, _external=True)
send_email(_(u'Your ban was lifted'), send_email(_(u'Your ban was lifted'),
Expand Down
2 changes: 1 addition & 1 deletion solace/views/admin.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def status(request):
def bans(request): def bans(request):
"""Manages banned users""" """Manages banned users"""
form = BanUserForm() form = BanUserForm()
query = User.query.banned() query = User.query.filter_by(is_banned=True)
pagination = Pagination(request, query, request.args.get('page', type=int)) pagination = Pagination(request, query, request.args.get('page', type=int))


if request.method == 'POST' and form.validate(): if request.method == 'POST' and form.validate():
Expand Down

0 comments on commit e2f1e4f

Please sign in to comment.