add limiter on custom alias page
This commit is contained in:
parent
e46e3b1c01
commit
71389b7e09
|
@ -9,9 +9,10 @@ from app.alias_utils import check_alias_prefix
|
||||||
from app.config import (
|
from app.config import (
|
||||||
DISABLE_ALIAS_SUFFIX,
|
DISABLE_ALIAS_SUFFIX,
|
||||||
CUSTOM_ALIAS_SECRET,
|
CUSTOM_ALIAS_SECRET,
|
||||||
|
ALIAS_LIMIT,
|
||||||
)
|
)
|
||||||
from app.dashboard.base import dashboard_bp
|
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.log import LOG
|
||||||
from app.models import (
|
from app.models import (
|
||||||
Alias,
|
Alias,
|
||||||
|
@ -93,6 +94,7 @@ def get_available_suffixes(user: User) -> [SuffixInfo]:
|
||||||
|
|
||||||
|
|
||||||
@dashboard_bp.route("/custom_alias", methods=["GET", "POST"])
|
@dashboard_bp.route("/custom_alias", methods=["GET", "POST"])
|
||||||
|
@limiter.limit(ALIAS_LIMIT, methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def custom_alias():
|
def custom_alias():
|
||||||
# check if user has not exceeded the alias quota
|
# 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
|
return False
|
||||||
|
|
||||||
user_custom_domains = [cd.domain for cd in user.verified_custom_domains()]
|
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
|
# make sure alias_suffix is either .random_word@simplelogin.co or @my-domain.com
|
||||||
alias_suffix = alias_suffix.strip()
|
alias_suffix = alias_suffix.strip()
|
||||||
|
|
|
@ -475,6 +475,13 @@ def setup_openid_metadata(app):
|
||||||
return jsonify(res)
|
return jsonify(res)
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_user():
|
||||||
|
try:
|
||||||
|
return g.user
|
||||||
|
except AttributeError:
|
||||||
|
return current_user
|
||||||
|
|
||||||
|
|
||||||
def setup_error_page(app):
|
def setup_error_page(app):
|
||||||
@app.errorhandler(400)
|
@app.errorhandler(400)
|
||||||
def bad_request(e):
|
def bad_request(e):
|
||||||
|
@ -503,7 +510,7 @@ def setup_error_page(app):
|
||||||
LOG.warning(
|
LOG.warning(
|
||||||
"Client hit rate limit on path %s, user:%s",
|
"Client hit rate limit on path %s, user:%s",
|
||||||
request.path,
|
request.path,
|
||||||
g.user or current_user,
|
get_current_user(),
|
||||||
)
|
)
|
||||||
if request.path.startswith("/api/"):
|
if request.path.startswith("/api/"):
|
||||||
return jsonify(error="Rate limit exceeded"), 429
|
return jsonify(error="Rate limit exceeded"), 429
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from flask import url_for
|
from flask import url_for, g
|
||||||
|
|
||||||
from app.alias_utils import delete_alias
|
from app.alias_utils import delete_alias
|
||||||
from app.config import EMAIL_DOMAIN
|
from app.config import EMAIL_DOMAIN
|
||||||
|
@ -23,7 +23,6 @@ from tests.utils import login
|
||||||
|
|
||||||
def test_add_alias_success(flask_client):
|
def test_add_alias_success(flask_client):
|
||||||
user = login(flask_client)
|
user = login(flask_client)
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
word = random_word()
|
word = random_word()
|
||||||
suffix = f".{word}@{EMAIL_DOMAIN}"
|
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):
|
def test_add_alias_in_custom_domain_trash(flask_client):
|
||||||
user = login(flask_client)
|
user = login(flask_client)
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
custom_domain = CustomDomain.create(
|
custom_domain = CustomDomain.create(
|
||||||
user_id=user.id, domain="ab.cd", verified=True, commit=True
|
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(
|
assert "You have deleted this alias before. You can restore it on" in r.get_data(
|
||||||
True
|
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)
|
||||||
|
|
Loading…
Reference in New Issue