add limiter on custom alias page

This commit is contained in:
Son NK 2021-03-24 16:52:05 +01:00
parent e46e3b1c01
commit 71389b7e09
3 changed files with 41 additions and 7 deletions

View File

@ -9,9 +9,10 @@ from app.alias_utils import check_alias_prefix
from app.config import (
DISABLE_ALIAS_SUFFIX,
CUSTOM_ALIAS_SECRET,
ALIAS_LIMIT,
)
from app.dashboard.base import dashboard_bp
from app.extensions import db
from app.extensions import db, limiter
from app.log import LOG
from app.models import (
Alias,
@ -93,6 +94,7 @@ def get_available_suffixes(user: User) -> [SuffixInfo]:
@dashboard_bp.route("/custom_alias", methods=["GET", "POST"])
@limiter.limit(ALIAS_LIMIT, methods=["POST"])
@login_required
def custom_alias():
# check if user has not exceeded the alias quota
@ -254,8 +256,6 @@ def verify_prefix_suffix(user: User, alias_prefix, alias_suffix) -> bool:
return False
user_custom_domains = [cd.domain for cd in user.verified_custom_domains()]
alias_prefix = alias_prefix.strip()
alias_prefix = convert_to_id(alias_prefix)
# make sure alias_suffix is either .random_word@simplelogin.co or @my-domain.com
alias_suffix = alias_suffix.strip()

View File

@ -475,6 +475,13 @@ def setup_openid_metadata(app):
return jsonify(res)
def get_current_user():
try:
return g.user
except AttributeError:
return current_user
def setup_error_page(app):
@app.errorhandler(400)
def bad_request(e):
@ -503,7 +510,7 @@ def setup_error_page(app):
LOG.warning(
"Client hit rate limit on path %s, user:%s",
request.path,
g.user or current_user,
get_current_user(),
)
if request.path.startswith("/api/"):
return jsonify(error="Rate limit exceeded"), 429

View File

@ -1,4 +1,4 @@
from flask import url_for
from flask import url_for, g
from app.alias_utils import delete_alias
from app.config import EMAIL_DOMAIN
@ -23,7 +23,6 @@ from tests.utils import login
def test_add_alias_success(flask_client):
user = login(flask_client)
db.session.commit()
word = random_word()
suffix = f".{word}@{EMAIL_DOMAIN}"
@ -238,7 +237,6 @@ def test_add_alias_in_global_trash(flask_client):
def test_add_alias_in_custom_domain_trash(flask_client):
user = login(flask_client)
db.session.commit()
custom_domain = CustomDomain.create(
user_id=user.id, domain="ab.cd", verified=True, commit=True
@ -273,3 +271,32 @@ def test_add_alias_in_custom_domain_trash(flask_client):
assert "You have deleted this alias before. You can restore it on" in r.get_data(
True
)
def test_too_many_requests(flask_client):
user = login(flask_client)
# create a custom domain
CustomDomain.create(user_id=user.id, domain="ab.cd", verified=True, commit=True)
# can't create more than 5 aliases in 1 minute
for i in range(7):
signed_suffix = signer.sign("@ab.cd").decode()
r = flask_client.post(
url_for("dashboard.custom_alias"),
data={
"prefix": f"prefix{i}",
"suffix": signed_suffix,
"mailboxes": [user.default_mailbox_id],
},
follow_redirects=True,
)
# to make flask-limiter work with unit test
# https://github.com/alisaifee/flask-limiter/issues/147#issuecomment-642683820
g._rate_limiting_complete = False
else:
# last request
assert r.status_code == 429
assert "Whoa, slow down there, pardner!" in str(r.data)