From 80d7d5281d668522b0dbb242d2e3cbd581d9feee Mon Sep 17 00:00:00 2001 From: justcool393 Date: Sun, 13 Nov 2022 00:07:15 -0600 Subject: [PATCH] ratelimit_user() wrapper --- files/helpers/wrappers.py | 3 +++ files/mail/__init__.py | 2 +- files/routes/awards.py | 3 ++- files/routes/comments.py | 10 +++++----- files/routes/login.py | 2 +- files/routes/oauth.py | 12 ++++++------ files/routes/posts.py | 10 +++++----- files/routes/reporting.py | 4 ++-- files/routes/settings.py | 36 ++++++++++++++++++------------------ files/routes/subs.py | 4 ++-- files/routes/users.py | 14 +++++++------- 11 files changed, 52 insertions(+), 48 deletions(-) diff --git a/files/helpers/wrappers.py b/files/helpers/wrappers.py index a6183daf3..8b525c59d 100644 --- a/files/helpers/wrappers.py +++ b/files/helpers/wrappers.py @@ -145,3 +145,6 @@ def feature_required(x): wrapper.__name__ = f.__name__ return wrapper return wrapper_maker + +def ratelimit_user(limit="1/second;20/minute;200/hour;1000/day"): + return limiter.limit(limit, key_func=lambda:f'{SITE}-{session.get("lo_user")}') diff --git a/files/mail/__init__.py b/files/mail/__init__.py index 54b925662..d2f69aec1 100644 --- a/files/mail/__init__.py +++ b/files/mail/__init__.py @@ -51,7 +51,7 @@ def send_verification_email(user, email=None): @app.post("/verify_email") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def verify_email(v): diff --git a/files/routes/awards.py b/files/routes/awards.py index 6b269c6b3..134bcfabc 100644 --- a/files/routes/awards.py +++ b/files/routes/awards.py @@ -121,7 +121,8 @@ def buy(v, award): @app.post("/award//") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() +@ratelimit_user() @is_not_permabanned @feature_required('AWARDS') def award_thing(v, thing_type, id): diff --git a/files/routes/comments.py b/files/routes/comments.py index 2bde33c9d..c65c4deeb 100644 --- a/files/routes/comments.py +++ b/files/routes/comments.py @@ -458,7 +458,7 @@ def edit_comment(cid, v): @app.post("/delete/comment/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def delete_comment(cid, v): @@ -486,7 +486,7 @@ def delete_comment(cid, v): @app.post("/undelete/comment/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def undelete_comment(cid, v): @@ -558,7 +558,7 @@ def unpin_comment(cid, v): @app.post("/save_comment/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def save_comment(cid, v): @@ -575,7 +575,7 @@ def save_comment(cid, v): @app.post("/unsave_comment/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def unsave_comment(cid, v): @@ -611,7 +611,7 @@ def diff_words(answer, guess): @app.post("/wordle/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def handle_wordle_action(cid, v): comment = get_comment(cid) diff --git a/files/routes/login.py b/files/routes/login.py index ba1343b0a..0e802fca3 100644 --- a/files/routes/login.py +++ b/files/routes/login.py @@ -181,7 +181,7 @@ def me(v): @app.post("/logout") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def logout(v): diff --git a/files/routes/oauth.py b/files/routes/oauth.py index e1e6fe3ce..6b9828e8b 100644 --- a/files/routes/oauth.py +++ b/files/routes/oauth.py @@ -18,7 +18,7 @@ def authorize_prompt(v): @app.post("/authorize") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def authorize(v): @@ -40,7 +40,7 @@ def authorize(v): @app.post("/rescind/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def rescind(v, aid): @@ -52,7 +52,7 @@ def rescind(v, aid): @app.post("/api_keys") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @is_not_permabanned def request_api_keys(v): @@ -94,7 +94,7 @@ def request_api_keys(v): @app.post("/delete_app/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def delete_oauth_app(v, aid): try: @@ -117,7 +117,7 @@ def delete_oauth_app(v, aid): @app.post("/edit_app/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @is_not_permabanned def edit_oauth_app(v, aid): try: @@ -285,7 +285,7 @@ def admin_apps_list(v): @app.post("/reroll/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def reroll_oauth_tokens(aid, v): diff --git a/files/routes/posts.py b/files/routes/posts.py index e7581f915..34d946f3f 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -79,7 +79,7 @@ def unclub_post(pid, v): @app.post("/publish/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def publish(pid, v): post = get_post(pid) @@ -955,7 +955,7 @@ def submit_post(v, sub=None): @app.post("/delete_post/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def delete_post_pid(pid, v): post = get_post(pid) @@ -982,7 +982,7 @@ def delete_post_pid(pid, v): @app.post("/undelete_post/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def undelete_post_pid(pid, v): post = get_post(pid) @@ -1038,7 +1038,7 @@ def toggle_post_nsfw(pid, v): @app.post("/save_post/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def save_post(pid, v): @@ -1054,7 +1054,7 @@ def save_post(pid, v): @app.post("/unsave_post/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def unsave_post(pid, v): diff --git a/files/routes/reporting.py b/files/routes/reporting.py index 738a666e4..280ec46d9 100644 --- a/files/routes/reporting.py +++ b/files/routes/reporting.py @@ -9,7 +9,7 @@ from files.helpers.sanitize import filter_emojis_only @app.post("/report/post/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def flag_post(pid, v): post = get_post(pid) @@ -62,7 +62,7 @@ def flag_post(pid, v): @app.post("/report/comment/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def flag_comment(cid, v): diff --git a/files/routes/settings.py b/files/routes/settings.py index 6fb831323..397c90874 100644 --- a/files/routes/settings.py +++ b/files/routes/settings.py @@ -28,7 +28,7 @@ def settings_personal(v): @app.delete('/settings/background') @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def remove_background(v): if v.background: @@ -38,7 +38,7 @@ def remove_background(v): @app.post("/settings/personal") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def settings_personal_post(v): updated = False @@ -319,21 +319,21 @@ def set_color(v:User, attr:str, color:Optional[str]): @app.post("/settings/namecolor") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def namecolor(v): return set_color(v, "namecolor", request.values.get("namecolor")) @app.post("/settings/themecolor") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def themecolor(v): return set_color(v, "themecolor", request.values.get("themecolor")) @app.post("/settings/gumroad") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def gumroad(v): if not (v.email and v.is_activated): @@ -369,14 +369,14 @@ def gumroad(v): @app.post("/settings/titlecolor") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def titlecolor(v): return set_color(v, "titlecolor", request.values.get("titlecolor")) @app.post("/settings/verifiedcolor") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def verifiedcolor(v): if not v.verified: abort(403, "You don't have a checkmark") @@ -384,7 +384,7 @@ def verifiedcolor(v): @app.post("/settings/security") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def settings_security_post(v): if request.values.get("new_password"): @@ -457,7 +457,7 @@ def settings_security_post(v): @app.post("/settings/log_out_all_others") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def settings_log_out_others(v): submitted_password = request.values.get("password", "").strip() @@ -472,7 +472,7 @@ def settings_log_out_others(v): @app.post("/settings/images/profile") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def settings_images_profile(v): if request.headers.get("cf-ipcountry") == "T1": abort(403, "Image uploads are not allowed through TOR.") @@ -507,7 +507,7 @@ def settings_images_profile(v): @app.post("/settings/images/banner") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required @feature_required('USERS_PROFILE_BANNER') def settings_images_banner(v): @@ -535,7 +535,7 @@ def settings_css_get(v): @app.post("/settings/css") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def settings_css(v): if v.agendaposter: abort(400, "Agendapostered users can't edit CSS!") @@ -549,7 +549,7 @@ def settings_css(v): @app.post("/settings/profilecss") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def settings_profilecss(v): profilecss = request.values.get("profilecss", v.profilecss).strip().replace('\\', '').strip()[:4000] @@ -598,7 +598,7 @@ def settings_block_user(v): @app.post("/settings/unblock") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def settings_unblock_user(v): user = get_user(request.values.get("username")) @@ -622,7 +622,7 @@ def settings_advanced_get(v): @app.post("/settings/name_change") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @is_not_permabanned def settings_name_change(v): new_name=request.values.get("name").strip() @@ -764,7 +764,7 @@ def settings_song_change(v): @app.post("/settings/title_change") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def settings_title_change(v): if v.flairchanged: abort(403) @@ -788,7 +788,7 @@ def settings_title_change(v): @app.post("/settings/pronouns_change") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required @feature_required('PRONOUNS') def settings_pronouns_change(v): @@ -815,7 +815,7 @@ def settings_pronouns_change(v): @app.post("/settings/checkmark_text") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def settings_checkmark_text(v): if not v.verified: abort(403) diff --git a/files/routes/subs.py b/files/routes/subs.py index 862e0f240..761362730 100644 --- a/files/routes/subs.py +++ b/files/routes/subs.py @@ -387,7 +387,7 @@ def sub_settings(v, sub): @app.post('/h//sidebar') @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @is_not_permabanned def post_sub_sidebar(v, sub): sub = get_sub_by_name(sub) @@ -412,7 +412,7 @@ def post_sub_sidebar(v, sub): @app.post('/h//css') @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @is_not_permabanned def post_sub_css(v, sub): sub = get_sub_by_name(sub) diff --git a/files/routes/users.py b/files/routes/users.py index abc30f5b9..6434f297a 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -313,14 +313,14 @@ def transfer_currency(v:User, username:str, currency_name:Literal['coins', 'proc @app.post("/@/transfer_coins") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @is_not_permabanned def transfer_coins(v, username): return transfer_currency(v, username, 'coins', True) @app.post("/@/transfer_bux") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @is_not_permabanned @feature_required('PROCOINS') def transfer_bux(v, username): @@ -393,7 +393,7 @@ def song(song): @app.post("/subscribe/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def subscribe(v, post_id): existing = g.db.query(Subscription).filter_by(user_id=v.id, submission_id=post_id).one_or_none() @@ -404,7 +404,7 @@ def subscribe(v, post_id): @app.post("/unsubscribe/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def unsubscribe(v, post_id): existing = g.db.query(Subscription).filter_by(user_id=v.id, submission_id=post_id).one_or_none() @@ -832,7 +832,7 @@ def u_user_id_info(id, v=None): @app.post("/follow/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def follow_user(username, v): @@ -859,7 +859,7 @@ def follow_user(username, v): @app.post("/unfollow/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def unfollow_user(username, v): @@ -887,7 +887,7 @@ def unfollow_user(username, v): @app.post("/remove_follow/") @limiter.limit("1/second;30/minute;200/hour;1000/day") -@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}') +@ratelimit_user() @auth_required def remove_follow(username, v): target = get_user(username)