Browse Source

Fix tests and rate limiting

sh4nks 9 years ago
parent
commit
7497a218c8

+ 24 - 2
flaskbb/auth/views.py

@@ -33,7 +33,21 @@ from flaskbb.utils.tokens import get_token_status
 auth = Blueprint("auth", __name__)
 
 
-def login_rate_limiting():
+@auth.before_request
+def check_rate_limiting():
+    """Check the the rate limits for each request for this blueprint."""
+    return limiter.check()
+
+
+@auth.errorhandler(429)
+def login_rate_limit_error(error):
+    """Register a custom error handler for a 'Too Many Requests'
+    (HTTP CODE 429) error."""
+    return render_template("errors/too_many_logins.html",
+                           timeout=error.description)
+
+
+def login_rate_limit():
     """Dynamically load the rate limiting config from the database."""
     # [count] [per|/] [n (optional)] [second|minute|hour|day|month|year]
     return "{count}/{timeout}minutes".format(
@@ -41,7 +55,15 @@ def login_rate_limiting():
         timeout=flaskbb_config["LOGIN_TIMEOUT"]
     )
 
-limiter.limit(login_rate_limiting, key_func=get_remote_address)(auth)
+
+def login_rate_limit_message():
+    """Display the amount of time left until the user can access the requested
+    resource again."""
+    return _("%(minutes)s minutes", minutes=flaskbb_config["LOGIN_TIMEOUT"])
+
+
+# Activate rate limiting on the whole blueprint
+limiter.limit(login_rate_limit, error_message=login_rate_limit_message)(auth)
 
 
 @auth.route("/login", methods=["GET", "POST"])

+ 3 - 3
flaskbb/fixtures/settings.py

@@ -84,18 +84,18 @@ fixture = (
                 'description':  "Enable to let the user activate their account by sending a email with an activation link."
             }),
             ('login_attempts', {
-                'value':        5,
+                'value':        15,
                 'value_type':   "integer",
                 'extra':        {'min': 1},
                 'name':         "Login Attempts",
-                'description':  "Number of failed login attempts before the account will be suspended for a specified time.",
+                'description':  "Number of requests on each 'auth' route before the user can try to access the route again.",
             }),
             ('login_timeout', {
                 'value':        15,
                 'value_type':   "integer",
                 'extra':        {'min': 0},
                 'name':         "Login Timeout",
-                'description':  "The time of how long a account will stay suspended until the user can try to login again (in minutes).",
+                'description':  "The timeout for how long the user has to wait until he can access the resource again (in minutes).",
             }),
             ('login_recaptcha', {
                 'value':        3,

+ 16 - 0
flaskbb/templates/errors/too_many_logins.html

@@ -0,0 +1,16 @@
+{% set page_title = _("Too Many Requests") %}
+
+{% extends theme("layout.html") %}
+{% block content %}
+
+<div class="panel page-panel">
+    <div class="panel-body page-body">
+        <div class="col-md-12 col-sm-12 col-xs-12">
+            <h1>{% trans %}Too Many Requests{% endtrans %}</h1>
+            <p>{% trans %}In order to prevent brute force attacks on accounts we have limited the amount of requests on this route.{% endtrans %}</p>
+            <p>Please try again in <strong>{{ timeout }}</strong>.</p>
+        </div>
+    </div>
+</div>
+
+{% endblock %}

+ 4 - 1
requirements.txt

@@ -8,6 +8,7 @@ flask-allows==0.1.0
 Flask-BabelPlus==1.0.1
 Flask-Cache==0.13.1
 Flask-DebugToolbar==0.10.0
+Flask-Limiter==0.9.3
 Flask-Login==0.3.2
 Flask-Mail==0.9.1
 Flask-Migrate==1.7.0
@@ -19,10 +20,12 @@ Flask-Themes2==0.1.4
 Flask-WTF==0.12
 itsdangerous==0.24
 Jinja2==2.8
+limits==1.1.1
 Mako==1.0.3
 MarkupSafe==0.23
 mistune==0.7.1
 Pygments==2.1
+python-editor==1.0
 pytz==2015.7
 redis==2.10.5
 requests==2.9.1
@@ -31,7 +34,7 @@ six==1.10.0
 speaklater==1.3
 SQLAlchemy==1.0.11
 SQLAlchemy-Utils==0.31.6
-Unidecode==0.04.19
+Unidecode==0.4.19
 Werkzeug==0.11.3
 Whoosh==2.7.0
 WTForms==2.1

+ 3 - 1
setup.py

@@ -62,8 +62,11 @@ setup(
     install_requires=[
         'Babel',
         'Flask',
+        'Flask-Allows',
+        'Flask-BabelPlus',
         'Flask-Cache',
         'Flask-DebugToolbar',
+        'Flask-Limiter',
         'Flask-Login',
         'Flask-Mail',
         'Flask-Migrate',
@@ -106,7 +109,6 @@ setup(
     ],
     dependency_links=[
         'https://github.com/jshipley/Flask-WhooshAlchemy/archive/master.zip#egg=Flask-WhooshAlchemy',
-        'https://github.com/sh4nks/flask-babelex/tarball/master#egg=Flask-BabelEx'
     ],
     classifiers=[
         'Development Status :: 4 - Beta',