diff --git a/files/mail/__init__.py b/files/mail/__init__.py index 492c27004..2be13d9d3 100644 --- a/files/mail/__init__.py +++ b/files/mail/__init__.py @@ -1,5 +1,4 @@ from os import environ -import requests import time from flask import * from urllib.parse import quote @@ -7,7 +6,7 @@ from urllib.parse import quote from files.helpers.security import * from files.helpers.wrappers import * from files.classes import * -from files.__main__ import app, mail +from files.__main__ import app, mail, limiter from flask_mail import Message site = environ.get("DOMAIN").strip() @@ -42,6 +41,7 @@ def send_verification_email(user, email=None): @app.post("/verify_email") +@limiter.limit("1/second") @auth_required def api_verify_email(v): diff --git a/files/routes/admin.py b/files/routes/admin.py index 441c365e4..e2a588f37 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -28,6 +28,7 @@ def truescore(v): @app.post("/@/revert_actions") +@limiter.limit("1/second") @admin_level_required(6) def revert_actions(v, username): if 'pcm' in request.host or ('rdrama' in request.host and v.id in [1,12,28,29,747,995,1480]) or ('rdrama' not in request.host and 'pcm' not in request.host): @@ -51,6 +52,7 @@ def revert_actions(v, username): return {"message": "Admin actions reverted!"} @app.post("/@/club_allow") +@limiter.limit("1/second") @admin_level_required(6) def club_allow(v, username): @@ -81,6 +83,7 @@ def club_allow(v, username): return {"message": f"@{username} has been allowed into the country club!"} @app.post("/@/club_ban") +@limiter.limit("1/second") @admin_level_required(6) def club_ban(v, username): @@ -110,6 +113,7 @@ def club_ban(v, username): @app.post("/@/make_admin") +@limiter.limit("1/second") @admin_level_required(6) def make_admin(v, username): if 'pcm' in request.host or ('rdrama' in request.host and v.id in [1,12,28,29,747,995,1480]) or ('rdrama' not in request.host and 'pcm' not in request.host): @@ -122,6 +126,7 @@ def make_admin(v, username): @app.post("/@/remove_admin") +@limiter.limit("1/second") @admin_level_required(6) def remove_admin(v, username): if 'pcm' in request.host or ('rdrama' in request.host and v.id in [1,12,28,29,747,995,1480]) or ('rdrama' not in request.host and 'pcm' not in request.host): @@ -134,6 +139,7 @@ def remove_admin(v, username): @app.post("/@/make_fake_admin") +@limiter.limit("1/second") @admin_level_required(6) def make_fake_admin(v, username): if 'pcm' in request.host or ('rdrama' in request.host and v.id in [1,12,28,29,747,995,1480]) or ('rdrama' not in request.host and 'pcm' not in request.host): @@ -146,6 +152,7 @@ def make_fake_admin(v, username): @app.post("/@/remove_fake_admin") +@limiter.limit("1/second") @admin_level_required(6) def remove_fake_admin(v, username): if 'pcm' in request.host or ('rdrama' in request.host and v.id in [1,12,28,29,747,995,1480]) or ('rdrama' not in request.host and 'pcm' not in request.host): @@ -228,6 +235,7 @@ def get_rules(v): @app.post('/admin/rules') +@limiter.limit("1/second") @admin_level_required(6) @validate_formkey def post_rules(v): @@ -331,6 +339,7 @@ def admin_home(v): return render_template("admin/admin_home.html", v=v, x=x) @app.post("/admin/disablesignups") +@limiter.limit("1/second") @admin_level_required(6) @validate_formkey def disablesignups(v): @@ -364,6 +373,7 @@ def badge_grant_get(v): @app.post("/admin/badge_grant") +@limiter.limit("1/second") @admin_level_required(4) @validate_formkey def badge_grant_post(v): @@ -592,6 +602,7 @@ def alt_votes_get(v): @app.post("/admin/link_accounts") +@limiter.limit("1/second") @admin_level_required(4) @validate_formkey def admin_link_accounts(v): @@ -638,6 +649,7 @@ def admin_removed(v): @app.post("/admin/image_ban") +@limiter.limit("1/second") @admin_level_required(4) @validate_formkey def admin_image_ban(v): @@ -693,6 +705,7 @@ def admin_image_ban(v): @app.post("/agendaposter/") +@limiter.limit("1/second") @admin_level_required(6) @validate_formkey def agendaposter(user_id, v): @@ -746,6 +759,7 @@ def agendaposter(user_id, v): @app.post("/shadowban/") +@limiter.limit("1/second") @admin_level_required(6) @validate_formkey def shadowban(user_id, v): @@ -771,6 +785,7 @@ def shadowban(user_id, v): @app.post("/unshadowban/") +@limiter.limit("1/second") @admin_level_required(6) @validate_formkey def unshadowban(user_id, v): @@ -795,6 +810,7 @@ def unshadowban(user_id, v): return {"message": "User unshadowbanned!"} @app.post("/admin/verify/") +@limiter.limit("1/second") @admin_level_required(6) @validate_formkey def verify(user_id, v): @@ -805,6 +821,7 @@ def verify(user_id, v): return {"message": "User verfied!"} @app.post("/admin/unverify/") +@limiter.limit("1/second") @admin_level_required(6) @validate_formkey def unverify(user_id, v): @@ -816,6 +833,7 @@ def unverify(user_id, v): @app.post("/admin/title_change/") +@limiter.limit("1/second") @admin_level_required(6) @validate_formkey def admin_title_change(user_id, v): @@ -849,6 +867,7 @@ def admin_title_change(user_id, v): return redirect(user.url) @app.post("/ban_user/") +@limiter.limit("1/second") @admin_level_required(6) @validate_formkey def ban_user(user_id, v): @@ -924,6 +943,7 @@ def ban_user(user_id, v): @app.post("/unban_user/") +@limiter.limit("1/second") @admin_level_required(6) @validate_formkey def unban_user(user_id, v): @@ -961,6 +981,7 @@ def unban_user(user_id, v): @app.post("/ban_post/") +@limiter.limit("1/second") @admin_level_required(3) @validate_formkey def ban_post(post_id, v): @@ -1004,6 +1025,7 @@ def ban_post(post_id, v): @app.post("/unban_post/") +@limiter.limit("1/second") @admin_level_required(3) @validate_formkey def unban_post(post_id, v): @@ -1037,6 +1059,7 @@ def unban_post(post_id, v): @app.post("/distinguish/") +@limiter.limit("1/second") @admin_level_required(1) @validate_formkey def api_distinguish_post(post_id, v): @@ -1062,6 +1085,7 @@ def api_distinguish_post(post_id, v): @app.post("/sticky/") +@limiter.limit("1/second") @admin_level_required(3) def api_sticky_post(post_id, v): @@ -1085,6 +1109,7 @@ def api_sticky_post(post_id, v): else: return {"message": "Post unpinned!"} @app.post("/pin/") +@limiter.limit("1/second") @auth_required def api_pin_post(post_id, v): @@ -1098,6 +1123,7 @@ def api_pin_post(post_id, v): else: return {"message": "Post unpinned!"} @app.post("/ban_comment/") +@limiter.limit("1/second") @admin_level_required(1) def api_ban_comment(c_id, v): @@ -1121,6 +1147,7 @@ def api_ban_comment(c_id, v): @app.post("/unban_comment/") +@limiter.limit("1/second") @admin_level_required(1) def api_unban_comment(c_id, v): @@ -1146,6 +1173,7 @@ def api_unban_comment(c_id, v): @app.post("/distinguish_comment/") +@limiter.limit("1/second") @auth_required def admin_distinguish_comment(c_id, v): @@ -1186,6 +1214,7 @@ def admin_banned_domains(v): return render_template("admin/banned_domains.html", v=v, banned_domains=banned_domains) @app.post("/admin/banned_domains") +@limiter.limit("1/second") @admin_level_required(4) @validate_formkey def admin_toggle_ban_domain(v): @@ -1207,6 +1236,7 @@ def admin_toggle_ban_domain(v): @app.post("/admin/nuke_user") +@limiter.limit("1/second") @admin_level_required(4) @validate_formkey def admin_nuke_user(v): @@ -1240,6 +1270,7 @@ def admin_nuke_user(v): @app.post("/admin/unnuke_user") +@limiter.limit("1/second") @admin_level_required(4) @validate_formkey def admin_nunuke_user(v): diff --git a/files/routes/awards.py b/files/routes/awards.py index fadb11190..158a3da9e 100644 --- a/files/routes/awards.py +++ b/files/routes/awards.py @@ -1,4 +1,4 @@ -from files.__main__ import app +from files.__main__ import app, limiter from files.helpers.wrappers import * from files.helpers.alerts import * from files.helpers.get import * @@ -85,6 +85,7 @@ def shop(v): @app.post("/buy/") +@limiter.limit("1/second") @auth_required def buy(v, award): if site_name == "Drama": @@ -185,6 +186,7 @@ ALLOW_MULTIPLE = ( ) @app.post("/post//awards") +@limiter.limit("1/second") @auth_required def award_post(pid, v): @@ -248,6 +250,7 @@ def award_post(pid, v): @app.post("/comment//awards") +@limiter.limit("1/second") @auth_required def award_comment(cid, v): @@ -320,6 +323,7 @@ def admin_userawards_get(v): return render_template("admin/user_award.html", awards=list(AWARDS.values()), v=v) @app.post("/admin/user_award") +@limiter.limit("1/second") @auth_required @validate_formkey def admin_userawards_post(v): diff --git a/files/routes/comments.py b/files/routes/comments.py index d0f874772..28345c885 100644 --- a/files/routes/comments.py +++ b/files/routes/comments.py @@ -120,8 +120,8 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None): @app.post("/comment") -@limiter.limit("6/minute") @limiter.limit("1/second") +@limiter.limit("6/minute") @is_not_banned @validate_formkey def api_comment(v): @@ -574,6 +574,7 @@ def api_comment(v): @app.post("/edit_comment/") +@limiter.limit("1/second") @auth_required @validate_formkey def edit_comment(cid, v): @@ -770,6 +771,7 @@ def edit_comment(cid, v): @app.post("/delete/comment/") +@limiter.limit("1/second") @auth_required @validate_formkey def delete_comment(cid, v): @@ -793,6 +795,7 @@ def delete_comment(cid, v): return {"message": "Comment deleted!"} @app.post("/undelete/comment/") +@limiter.limit("1/second") @auth_required @validate_formkey def undelete_comment(cid, v): @@ -817,6 +820,7 @@ def undelete_comment(cid, v): @app.post("/pin_comment/") +@limiter.limit("1/second") @auth_required @validate_formkey def toggle_pin_comment(cid, v): @@ -847,6 +851,7 @@ def toggle_pin_comment(cid, v): @app.post("/save_comment/") +@limiter.limit("1/second") @auth_required @validate_formkey def save_comment(cid, v): @@ -858,12 +863,12 @@ def save_comment(cid, v): if not save: new_save=SaveRelationship(user_id=v.id, submission_id=comment.id, type=2) g.db.add(new_save) - try: g.db.commit() - except: g.db.rollback() + g.db.commit() return {"message": "Comment saved!"} @app.post("/unsave_comment/") +@limiter.limit("1/second") @auth_required @validate_formkey def unsave_comment(cid, v): diff --git a/files/routes/errors.py b/files/routes/errors.py index 3e6241dd2..7835ee4c9 100644 --- a/files/routes/errors.py +++ b/files/routes/errors.py @@ -5,7 +5,7 @@ from files.helpers.session import * from flask import * from urllib.parse import quote, urlencode import time -from files.__main__ import app +from files.__main__ import app, limiter # Errors @@ -67,6 +67,7 @@ def error_500(e, v): @app.post("/allow_nsfw") +@limiter.limit("1/second") def allow_nsfw(): session["over_18"] = int(time.time()) + 3600 diff --git a/files/routes/login.py b/files/routes/login.py index 68175cbc7..176e60a0a 100644 --- a/files/routes/login.py +++ b/files/routes/login.py @@ -77,6 +77,7 @@ def check_for_alts(current_id): @app.post("/login") +@limiter.limit("1/second") @limiter.limit("6/minute") def login_post(): @@ -165,6 +166,7 @@ def me(v): @app.post("/logout") +@limiter.limit("1/second") @auth_required @validate_formkey def logout(v): @@ -225,6 +227,7 @@ def sign_up_get(v): @app.post("/signup") +@limiter.limit("1/second") @limiter.limit("5/day") @auth_desired def sign_up_post(v): @@ -376,6 +379,7 @@ def get_forgot(): @app.post("/forgot") +@limiter.limit("1/second") def post_forgot(): username = request.values.get("username").lstrip('@') @@ -445,6 +449,7 @@ def get_reset(): @app.post("/reset") +@limiter.limit("1/second") @auth_desired def post_reset(v): if v: @@ -497,6 +502,7 @@ def lost_2fa(v): ) @app.post("/request_2fa_disable") +@limiter.limit("1/second") @limiter.limit("6/minute") def request_2fa_disable(): diff --git a/files/routes/oauth.py b/files/routes/oauth.py index 450e60b33..124948696 100644 --- a/files/routes/oauth.py +++ b/files/routes/oauth.py @@ -4,7 +4,7 @@ from files.helpers.get import * from files.helpers.const import * from files.classes import * from flask import * -from files.__main__ import app +from files.__main__ import app, limiter from sqlalchemy.orm import joinedload @app.get("/authorize") @@ -17,6 +17,7 @@ def authorize_prompt(v): @app.post("/authorize") +@limiter.limit("1/second") @auth_required @validate_formkey def authorize(v): @@ -39,6 +40,7 @@ def authorize(v): @app.post("/api_keys") +@limiter.limit("1/second") @is_not_banned def request_api_keys(v): @@ -59,6 +61,7 @@ def request_api_keys(v): @app.post("/delete_app/") +@limiter.limit("1/second") @auth_required @validate_formkey def delete_oauth_app(v, aid): @@ -77,6 +80,7 @@ def delete_oauth_app(v, aid): @app.post("/edit_app/") +@limiter.limit("1/second") @is_not_banned @validate_formkey def edit_oauth_app(v, aid): @@ -96,6 +100,7 @@ def edit_oauth_app(v, aid): @app.post("/admin/app/approve/") +@limiter.limit("1/second") @admin_level_required(3) @validate_formkey def admin_app_approve(v, aid): @@ -123,6 +128,7 @@ def admin_app_approve(v, aid): @app.post("/admin/app/revoke/") +@limiter.limit("1/second") @admin_level_required(3) @validate_formkey def admin_app_revoke(v, aid): @@ -141,6 +147,7 @@ def admin_app_revoke(v, aid): @app.post("/admin/app/reject/") +@limiter.limit("1/second") @admin_level_required(3) @validate_formkey def admin_app_reject(v, aid): @@ -223,6 +230,7 @@ def admin_apps_list(v): @app.post("/oauth/reroll/") +@limiter.limit("1/second") @auth_required def reroll_oauth_tokens(aid, v): diff --git a/files/routes/posts.py b/files/routes/posts.py index c9c4ea33c..30960c5e7 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -25,6 +25,7 @@ with open("snappy.txt", "r") as f: snappyquotes = f.read().split("{[para]}") @app.post("/toggle_club/") +@limiter.limit("1/second") @auth_required def toggle_club(pid, v): @@ -50,6 +51,7 @@ def toggle_club(pid, v): @app.post("/publish/") +@limiter.limit("1/second") @auth_required @validate_formkey def publish(pid, v): @@ -188,6 +190,7 @@ def post_id(pid, anything=None, v=None): @app.post("/edit_post/") +@limiter.limit("1/second") @auth_required @validate_formkey def edit_post(pid, v): @@ -501,6 +504,7 @@ def thumbnail_thread(pid): @app.post("/submit") +@limiter.limit("1/second") @limiter.limit("6/minute") @is_not_banned @validate_formkey @@ -958,6 +962,7 @@ def submit_post(v): @app.post("/delete_post/") +@limiter.limit("1/second") @auth_required @validate_formkey def delete_post_pid(pid, v): @@ -979,6 +984,7 @@ def delete_post_pid(pid, v): return {"message": "Post deleted!"} @app.post("/undelete_post/") +@limiter.limit("1/second") @auth_required @validate_formkey def undelete_post_pid(pid, v): @@ -995,6 +1001,7 @@ def undelete_post_pid(pid, v): @app.post("/toggle_comment_nsfw/") +@limiter.limit("1/second") @auth_required @validate_formkey def toggle_comment_nsfw(cid, v): @@ -1011,6 +1018,7 @@ def toggle_comment_nsfw(cid, v): else: return {"message": "Comment has been unmarked as +18!"} @app.post("/toggle_post_nsfw/") +@limiter.limit("1/second") @auth_required @validate_formkey def toggle_post_nsfw(pid, v): @@ -1037,6 +1045,7 @@ def toggle_post_nsfw(pid, v): else: return {"message": "Post has been unmarked as +18!"} @app.post("/save_post/") +@limiter.limit("1/second") @auth_required @validate_formkey def save_post(pid, v): @@ -1053,6 +1062,7 @@ def save_post(pid, v): return {"message": "Post saved!"} @app.post("/unsave_post/") +@limiter.limit("1/second") @auth_required @validate_formkey def unsave_post(pid, v): diff --git a/files/routes/reporting.py b/files/routes/reporting.py index ed925f2cd..046c56402 100644 --- a/files/routes/reporting.py +++ b/files/routes/reporting.py @@ -1,10 +1,11 @@ from files.helpers.wrappers import * from files.helpers.get import * from flask import g -from files.__main__ import app +from files.__main__ import app, limiter from os import path @app.post("/flag/post/") +@limiter.limit("1/second") @auth_desired def api_flag_post(pid, v): @@ -36,6 +37,7 @@ def api_flag_post(pid, v): @app.post("/flag/comment/") +@limiter.limit("1/second") @auth_desired def api_flag_comment(cid, v): @@ -66,6 +68,7 @@ def api_flag_comment(cid, v): @app.post('/del_report/') +@limiter.limit("1/second") @auth_required @validate_formkey def remove_report(report_fn, v): diff --git a/files/routes/settings.py b/files/routes/settings.py index f905a8060..957c9a327 100644 --- a/files/routes/settings.py +++ b/files/routes/settings.py @@ -6,7 +6,7 @@ from files.helpers.markdown import * from files.helpers.discord import remove_user, set_nick from files.helpers.const import * from files.mail import * -from files.__main__ import app, cache +from files.__main__ import app, cache, limiter import youtube_dl from .front import frontlist import os @@ -30,6 +30,7 @@ tiers={ } @app.post("/settings/removebackground") +@limiter.limit("1/second") @auth_required def removebackground(v): v.background = None @@ -38,6 +39,7 @@ def removebackground(v): return {"message": "Background removed!"} @app.post("/settings/profile") +@limiter.limit("1/second") @auth_required @validate_formkey def settings_profile_post(v): @@ -248,6 +250,7 @@ def settings_profile_post(v): return {"error": "You didn't change anything."}, 400 @app.post("/changelogsub") +@limiter.limit("1/second") @auth_required @validate_formkey def changelogsub(v): @@ -261,6 +264,7 @@ def changelogsub(v): else: return {"message": "You have unsubscribed from the changelog!"} @app.post("/settings/namecolor") +@limiter.limit("1/second") @auth_required @validate_formkey def namecolor(v): @@ -273,6 +277,7 @@ def namecolor(v): return redirect("/settings/profile") @app.post("/settings/themecolor") +@limiter.limit("1/second") @auth_required @validate_formkey def themecolor(v): @@ -285,6 +290,7 @@ def themecolor(v): return redirect("/settings/profile") @app.post("/settings/gumroad") +@limiter.limit("1/second") @auth_required @validate_formkey def gumroad(v): @@ -359,6 +365,7 @@ def gumroad(v): return {"message": f"{patron} rewards claimed!"} @app.post("/settings/titlecolor") +@limiter.limit("1/second") @auth_required @validate_formkey def titlecolor(v): @@ -372,6 +379,7 @@ def titlecolor(v): return redirect("/settings/profile") @app.post("/settings/security") +@limiter.limit("1/second") @auth_required @validate_formkey def settings_security_post(v): @@ -475,6 +483,7 @@ def settings_security_post(v): escape("Two-factor authentication disabled.")) @app.post("/settings/log_out_all_others") +@limiter.limit("1/second") @auth_required @validate_formkey def settings_log_out_others(v): @@ -497,6 +506,7 @@ def settings_log_out_others(v): @app.post("/settings/images/profile") +@limiter.limit("1/second") @auth_required @validate_formkey def settings_images_profile(v): @@ -528,6 +538,7 @@ def settings_images_profile(v): @app.post("/settings/images/banner") +@limiter.limit("1/second") @auth_required @validate_formkey def settings_images_banner(v): @@ -550,6 +561,7 @@ def settings_images_banner(v): @app.post("/settings/delete/profile") +@limiter.limit("1/second") @auth_required @validate_formkey def settings_delete_profile(v): @@ -561,6 +573,7 @@ def settings_delete_profile(v): msg="Profile picture successfully removed.") @app.post("/settings/delete/banner") +@limiter.limit("1/second") @auth_required @validate_formkey def settings_delete_banner(v): @@ -586,6 +599,7 @@ def settings_css_get(v): return render_template("settings_css.html", v=v) @app.post("/settings/css") +@limiter.limit("1/second") @auth_required def settings_css(v): css = request.values.get("css").replace('\\', '')[:50000] @@ -607,6 +621,7 @@ def settings_profilecss_get(v): return render_template("settings_profilecss.html", v=v) @app.post("/settings/profilecss") +@limiter.limit("1/second") @auth_required def settings_profilecss(v): if v.coins < 1000 and not v.patron: return f"You must have +1000 {COINS_NAME} or be a patron to set profile css." @@ -618,6 +633,7 @@ def settings_profilecss(v): return render_template("settings_profilecss.html", v=v) @app.post("/settings/block") +@limiter.limit("1/second") @auth_required @validate_formkey def settings_block_user(v): @@ -655,6 +671,7 @@ def settings_block_user(v): @app.post("/settings/unblock") +@limiter.limit("1/second") @auth_required @validate_formkey def settings_unblock_user(v): @@ -689,6 +706,7 @@ def settings_apps(v): @app.post("/settings/remove_discord") +@limiter.limit("1/second") @auth_required @validate_formkey def settings_remove_discord(v): @@ -709,6 +727,7 @@ def settings_content_get(v): return render_template("settings_filters.html", v=v) @app.post("/settings/name_change") +@limiter.limit("1/second") @auth_required @validate_formkey def settings_name_change(v): @@ -758,6 +777,7 @@ def settings_name_change(v): return redirect("/settings/profile") @app.post("/settings/song_change") +@limiter.limit("1/second") @auth_required @validate_formkey def settings_song_change(v): @@ -839,6 +859,7 @@ def settings_song_change(v): return redirect("/settings/profile") @app.post("/settings/title_change") +@limiter.limit("1/second") @auth_required @validate_formkey def settings_title_change(v): diff --git a/files/routes/static.py b/files/routes/static.py index 2f2741162..fe7472ec3 100644 --- a/files/routes/static.py +++ b/files/routes/static.py @@ -222,6 +222,7 @@ def contact(v): return render_template("contact.html", v=v) @app.post("/contact") +@limiter.limit("1/second") @auth_required def submit_contact(v): message = f'This message has been sent automatically to all admins via https://{site}/contact, user email is "{v.email}"\n\nMessage:\n\n' + request.values.get("message", "") @@ -333,6 +334,7 @@ def settings_security(v): ) @app.post("/dismiss_mobile_tip") +@limiter.limit("1/second") def dismiss_mobile_tip(): session["tooltip_last_dismissed"]=int(time.time()) diff --git a/files/routes/users.py b/files/routes/users.py index ee9b246a8..9f0545d41 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -21,6 +21,7 @@ beams_client = PushNotifications( @app.post("/pay_rent") +@limiter.limit("1/second") @auth_required def pay_rent(v): if v.coins < 500: return "You must have more than 500 coins." @@ -36,6 +37,7 @@ def pay_rent(v): @app.post("/steal") +@limiter.limit("1/second") @is_not_banned def steal(v): if int(time.time()) - v.created_utc < 604800: @@ -89,6 +91,7 @@ def thiefs(v): @app.post("/@/suicide") +@limiter.limit("1/second") @auth_required def suicide(v, username): t = int(time.time()) @@ -110,6 +113,7 @@ def get_coins(v, username): else: return {"error": "invalid_user"}, 404 @app.post("/@/transfer_coins") +@limiter.limit("1/second") @is_not_banned @validate_formkey def transfer_coins(v, username): @@ -198,6 +202,7 @@ def song(song): return resp @app.post("/subscribe/") +@limiter.limit("1/second") @auth_required def subscribe(v, post_id): new_sub = Subscription(user_id=v.id, submission_id=post_id) @@ -206,6 +211,7 @@ def subscribe(v, post_id): return {"message": "Post subscribed!"} @app.post("/unsubscribe/") +@limiter.limit("1/second") @auth_required def unsubscribe(v, post_id): sub=g.db.query(Subscription).options(lazyload('*')).filter_by(user_id=v.id, submission_id=post_id).first() @@ -215,6 +221,7 @@ def unsubscribe(v, post_id): return {"message": "Post unsubscribed!"} @app.post("/@/message") +@limiter.limit("1/second") @limiter.limit("10/hour") @auth_required def message2(v, username): @@ -277,6 +284,7 @@ def message2(v, username): @app.post("/reply") +@limiter.limit("1/second") @limiter.limit("6/minute") @auth_required def messagereply(v): @@ -608,6 +616,7 @@ def u_username_info(username, v=None): @app.post("/follow/") +@limiter.limit("1/second") @auth_required def follow_user(username, v): @@ -621,9 +630,7 @@ def follow_user(username, v): new_follow = Follow(user_id=v.id, target_id=target.id) g.db.add(new_follow) - try: g.db.flush() - except: g.db.rollback() - + g.db.flush() target.stored_subscriber_count = g.db.query(Follow.id).options(lazyload('*')).filter_by(target_id=target.id).count() g.db.add(target) @@ -635,6 +642,7 @@ def follow_user(username, v): return {"message": "User followed!"} @app.post("/unfollow/") +@limiter.limit("1/second") @auth_required def unfollow_user(username, v): @@ -661,6 +669,7 @@ def unfollow_user(username, v): return {"message": "User unfollowed!"} @app.post("/remove_follow/") +@limiter.limit("1/second") @auth_required def remove_follow(username, v): target = get_user(username) diff --git a/files/routes/votes.py b/files/routes/votes.py index aa76f21ce..6d21dd94c 100644 --- a/files/routes/votes.py +++ b/files/routes/votes.py @@ -2,7 +2,7 @@ from files.helpers.wrappers import * from files.helpers.get import * from files.classes import * from flask import * -from files.__main__ import app +from files.__main__ import app, limiter from sqlalchemy.orm import joinedload @@ -56,6 +56,7 @@ def admin_vote_info_get(v): @app.post("/vote/post//") +@limiter.limit("1/second") @auth_required @validate_formkey def api_vote_post(post_id, new, v): @@ -97,16 +98,15 @@ def api_vote_post(post_id, new, v): ) g.db.add(vote) - try: - g.db.flush() - post.upvotes = g.db.query(Vote.id).options(lazyload('*')).filter_by(submission_id=post.id, vote_type=1).count() - post.downvotes = g.db.query(Vote.id).options(lazyload('*')).filter_by(submission_id=post.id, vote_type=-1).count() - g.db.add(post) - g.db.commit() - except: g.db.rollback() + g.db.flush() + post.upvotes = g.db.query(Vote.id).options(lazyload('*')).filter_by(submission_id=post.id, vote_type=1).count() + post.downvotes = g.db.query(Vote.id).options(lazyload('*')).filter_by(submission_id=post.id, vote_type=-1).count() + g.db.add(post) + g.db.commit() return "", 204 @app.post("/vote/comment//") +@limiter.limit("1/second") @auth_required @validate_formkey def api_vote_comment(comment_id, new, v): @@ -153,17 +153,16 @@ def api_vote_comment(comment_id, new, v): g.db.add(vote) - try: - g.db.flush() - comment.upvotes = g.db.query(CommentVote.id).options(lazyload('*')).filter_by(comment_id=comment.id, vote_type=1).count() - comment.downvotes = g.db.query(CommentVote.id).options(lazyload('*')).filter_by(comment_id=comment.id, vote_type=-1).count() - g.db.add(comment) - g.db.commit() - except: g.db.rollback() + g.db.flush() + comment.upvotes = g.db.query(CommentVote.id).options(lazyload('*')).filter_by(comment_id=comment.id, vote_type=1).count() + comment.downvotes = g.db.query(CommentVote.id).options(lazyload('*')).filter_by(comment_id=comment.id, vote_type=-1).count() + g.db.add(comment) + g.db.commit() return "", 204 @app.post("/vote/poll/") +@limiter.limit("1/second") @auth_required def api_vote_poll(comment_id, v):