diff options
Diffstat (limited to 'ihatemoney/web.py')
| -rw-r--r-- | ihatemoney/web.py | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/ihatemoney/web.py b/ihatemoney/web.py index 65c0ed6..cc2eeac 100644 --- a/ihatemoney/web.py +++ b/ihatemoney/web.py @@ -27,10 +27,12 @@ from ihatemoney.forms import ( InviteForm, MemberForm, PasswordReminder, ProjectForm, get_billform_for, ExportForm ) -from ihatemoney.utils import Redirect303, list_of_dicts2json, list_of_dicts2csv +from ihatemoney.utils import Redirect303, list_of_dicts2json, list_of_dicts2csv, LoginThrottler main = Blueprint("main", __name__) +login_throttler = LoginThrottler(max_attempts=3, delay=1) + def requires_admin(f): """Require admin permissions for @requires_admin decorated endpoints. @@ -89,14 +91,24 @@ def admin(): form = AdminAuthenticationForm() goto = request.args.get('goto', url_for('.home')) if request.method == "POST": + client_ip = request.remote_addr + if not login_throttler.is_login_allowed(client_ip): + msg = _("Too many failed login attempts, please retry later.") + form.errors['admin_password'] = [msg] + return render_template("authenticate.html", form=form, admin_auth=True) if form.validate(): - if check_password_hash(current_app.config['ADMIN_PASSWORD'], form.admin_password.data): + # Valid password + if (check_password_hash(current_app.config['ADMIN_PASSWORD'], + form.admin_password.data)): session['is_admin'] = True session.update() + login_throttler.reset(client_ip) return redirect(goto) - else: - msg = _("This admin password is not the right one") - form.errors['admin_password'] = [msg] + # Invalid password + login_throttler.increment_attempts_counter(client_ip) + msg = _("This admin password is not the right one. Only %(num)d attempts left.", + num=login_throttler.get_remaining_attempts(client_ip)) + form.errors['admin_password'] = [msg] return render_template("authenticate.html", form=form, admin_auth=True) |
