Commits

Anonymous committed d871448

It's now possible to ban users.

Comments (0)

Files changed (7)

         request object will call this function for those two attributes.
 
         If the user is not logged in, the return value has to be `None`.
+        This method also has to check if the user was not banned.  If the
+        user is banned, it has to ensure that `None` is returned and
+        should ensure that future requests do not trigger this method.
 
         Most auth systems do not have to implement this method.
         """
         user_id = request.session.get('user_id')
         if user_id is not None:
-            return User.query.get(user_id)
+            user = User.query.get(user_id)
+            if user is not None and user.is_banned:
+                del request.session['user_id']
+            else:
+                return user
 
     def set_user(self, request, user):
         """Can be used by the login function to set the user.  This function
         if user is None:
             user = self.request.user
         return Comment(self.post, user, self['text'])
+
+
+class BanUserForm(forms.Form):
+    """Used to ban new users."""
+    username = forms.TextField(lazy_gettext(u'Username'), required=True)
+
+    def validate_username(self, value):
+        self.user = User.query.filter_by(username=value).first()
+        if self.user is None:
+            raise forms.ValidationError(_(u'No such user.'))
         return self.filter(User.id.in_(select([ua.user_id],
                                               ua.locale == str(locale))))
 
+    def banned(self):
+        """Returns all the banned users."""
+        return self.filter_by(pw_hash=None)
+
 
 class User(RemoteObject):
     """Represents a user on the system."""

solace/templates/admin/bans.html

+{% extends 'admin/layout.html' %}
+{% from '_helpers.html' import render_user %}
+{% block admin_body %}
+  <h2>{{ _('Bans') }}</h2>
+  <p>{% trans -%}
+    Ban and unban users.
+  {%- endtrans %}
+  <h3>{{ _('Add a new ban') }}</h3>
+  <p>{% trans -%}
+    In order to ban a user visit his profile and follow the
+    “ban user” link or enter his username into the following field:
+  {%- endtrans %}
+  {% call form() %}
+    {{ form.as_dl() }}
+    <div class="submit">
+      <input type="submit" value="{{ _('Ban user') }}">
+    </div>
+  {% endcall %}
+  {% if banned_users %}
+  <h3>{{ _('Banned Users') }}</h3>
+  <ul class="userlist">
+  {%- for user in banned_users %}
+    <li>{{ render_user(user, avatar_size=26) }}
+  {%- endfor %}
+  </ul>
+  {% endif %}
+  {{ pagination }}
+{% endblock %}

solace/templates/mails/user_banned.txt

+{% extends 'mails/layout.txt' -%}
+{% block body %}{% trans user=user.display_name -%}
+Hi {{ user }}!
+
+We're sorry to inform you, but you were banned from the
+system for abusing the terms of service.  In order to
+find out more, please contact an administrator of the
+system.
+{%- endtrans %}{% endblock %}

solace/utils/admin.py

+# -*- coding: utf-8 -*-
+"""
+    solace.utils.admin
+    ~~~~~~~~~~~~~~~~~~
+
+    Admin helpers.
+
+    :copyright: (c) 2009 by Plurk Inc., see AUTHORS for more details.
+    :license: BSD, see LICENSE for more details.
+"""
+from solace.i18n import _
+from solace.utils.email import send_email
+from solace.models import User, session
+
+
+def ban_user(user):
+    """Bans a user if it was not already banned.  This also sends the
+    user an email that he was banned.
+    """
+    if user.is_banned:
+        return
+
+    user.pw_hash = None
+    send_email(_(u'User account banned'),
+               render_template('mails/user_banned.txt', user=user),
+               user.email)
+    session.commit()

solace/views/admin.py

 from werkzeug import redirect, Response
 from werkzeug.exceptions import Forbidden
 
+from solace.i18n import _
 from solace.application import require_admin, url_for
+from solace.models import User, session
+from solace.forms import BanUserForm
 from solace.settings import describe_settings
 from solace.templating import render_template
+from solace.utils.pagination import Pagination
+from solace.utils.admin import ban_user
 
 
 @require_admin
     """Displays system statistics such as the database settings."""
     return render_template('admin/status.html',
                            active_settings=describe_settings())
+
+
+@require_admin
+def bans(request):
+    """Manages banned users"""
+    form = BanUserForm()
+    query = User.query.banned()
+    pagination = Pagination(request, query, request.args.get('page', type=int))
+
+    if request.method == 'POST' and form.validate():
+        ban_user(form.user)
+        request.flash(_(u'The user “%s” was successfully banned.') %
+                      form.user.username)
+        return form.redirect('admin.bans')
+
+    return render_template('admin/bans.html', pagination=pagination,
+                           banned_users=pagination.get_objects(),
+                           form=form.as_widget())