default ratelimit doesnt apply implicitly if theres other @limiter.limit before the function, so add it explicity before all functions

pull/134/head
Aevann 2023-02-26 10:41:04 +02:00
parent 152948b658
commit 8c495c914a
28 changed files with 326 additions and 23 deletions

View File

@ -60,8 +60,9 @@ if "load_chat" in argv:
def get_CF():
with app.app_context():
x = request.headers.get('CF-Connecting-IP')
if x: return x
return request.headers.get('X-Forwarded-For')
if not x:
x = request.headers.get('X-Forwarded-For')
return x
limiter = Limiter(
app=app,

View File

@ -25,6 +25,7 @@ from files.routes.routehelpers import get_alt_graph, get_alt_graph_ids
from .front import frontlist, comment_idlist
@app.get('/admin/loggedin')
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['VIEW_ACTIVE_USERS'])
def loggedin_list(v):
@ -33,6 +34,7 @@ def loggedin_list(v):
return render_template("admin/loggedin.html", v=v, users=users)
@app.get('/admin/loggedout')
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['VIEW_ACTIVE_USERS'])
def loggedout_list(v):
@ -40,6 +42,7 @@ def loggedout_list(v):
return render_template("admin/loggedout.html", v=v, users=users)
@app.get('/admin/dm_images')
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['VIEW_DM_IMAGES'])
def dm_images(v):
@ -60,6 +63,7 @@ def dm_images(v):
return render_template("admin/dm_images.html", v=v, items=items, next_exists=next_exists, page=page)
@app.get('/admin/edit_rules')
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['EDIT_RULES'])
def edit_rules_get(v):
@ -92,6 +96,7 @@ def edit_rules_post(v):
@app.post("/@<username>/make_admin")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['ADMIN_ADD'])
def make_admin(v:User, username):
@ -114,6 +119,7 @@ def make_admin(v:User, username):
@app.post("/@<username>/remove_admin")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['ADMIN_REMOVE'])
def remove_admin(v:User, username):
@ -142,6 +148,7 @@ def remove_admin(v:User, username):
@app.post("/distribute/<int:option_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_BETS_DISTRIBUTE'])
def distribute(v:User, option_id):
@ -200,6 +207,7 @@ def distribute(v:User, option_id):
@app.post("/@<username>/revert_actions")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['ADMIN_ACTIONS_REVERT'])
def revert_actions(v:User, username):
@ -253,6 +261,7 @@ def revert_actions(v:User, username):
return {"message": f"@{revertee.username}'s admin actions have been reverted!"}
@app.get("/admin/shadowbanned")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_SHADOWBAN'])
def shadowbanned(v):
@ -266,6 +275,7 @@ def shadowbanned(v):
@app.get("/admin/image_posts")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def image_posts_listing(v):
@ -285,6 +295,7 @@ def image_posts_listing(v):
@app.get("/admin/reported/posts")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def reported_posts(v):
@ -309,6 +320,7 @@ def reported_posts(v):
@app.get("/admin/reported/comments")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def reported_comments(v):
@ -337,6 +349,7 @@ def reported_comments(v):
standalone=True)
@app.get("/admin")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['ADMIN_HOME_VISIBLE'])
def admin_home(v):
@ -344,6 +357,7 @@ def admin_home(v):
@app.post("/admin/site_settings/<setting>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['SITE_SETTINGS'])
def change_settings(v:User, setting):
@ -372,6 +386,7 @@ def change_settings(v:User, setting):
@app.post("/admin/clear_cloudflare_cache")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['SITE_CACHE_PURGE_CDN'])
def clear_cloudflare_cache(v):
@ -396,6 +411,7 @@ def admin_badges_grantable_list(v):
@app.get("/admin/badge_grant")
@app.get("/admin/badge_remove")
@feature_required('BADGES')
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_BADGES'])
def badge_grant_get(v):
@ -406,8 +422,9 @@ def badge_grant_get(v):
badge_types=badge_types, grant=grant)
@app.post("/admin/badge_grant")
@limiter.limit('1/second', scope=path)
@feature_required('BADGES')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_BADGES'])
def badge_grant_post(v):
@ -467,8 +484,9 @@ def badge_grant_post(v):
return render_template("admin/badge_admin.html", v=v, badge_types=badges, grant=True, msg=f"{new_badge.name} Badge granted to @{user.username} successfully!")
@app.post("/admin/badge_remove")
@limiter.limit('1/second', scope=path)
@feature_required('BADGES')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_BADGES'])
def badge_remove_post(v):
@ -504,6 +522,7 @@ def badge_remove_post(v):
@app.get("/admin/alt_votes")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['VIEW_ALT_VOTES'])
def alt_votes_get(v):
@ -610,6 +629,7 @@ def alt_votes_get(v):
@app.get("/admin/alts/")
@app.get("/@<username>/alts/")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_LINK'])
def admin_view_alts(v:User, username=None):
@ -618,6 +638,7 @@ def admin_view_alts(v:User, username=None):
@app.post('/@<username>/alts/')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_LINK'])
def admin_add_alt(v:User, username):
@ -653,6 +674,7 @@ def admin_add_alt(v:User, username):
@app.post('/@<username>/alts/<int:other>/deleted')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_LINK'])
def admin_delink_relink_alt(v:User, username, other):
@ -675,6 +697,7 @@ def admin_delink_relink_alt(v:User, username, other):
@app.get("/admin/removed/posts")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def admin_removed(v):
@ -697,6 +720,7 @@ def admin_removed(v):
@app.get("/admin/removed/comments")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def admin_removed_comments(v):
@ -717,6 +741,7 @@ def admin_removed_comments(v):
@app.post("/unagendaposter/<id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_AGENDAPOSTER'])
def unagendaposter(id, v):
@ -757,6 +782,7 @@ def unagendaposter(id, v):
@app.post("/shadowban/<int:user_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_SHADOWBAN'])
def shadowban(user_id, v):
@ -792,6 +818,7 @@ def shadowban(user_id, v):
@app.post("/unshadowban/<int:user_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_SHADOWBAN'])
def unshadowban(user_id, v):
@ -819,6 +846,7 @@ def unshadowban(user_id, v):
@app.post("/admin/title_change/<int:user_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_TITLE_CHANGE'])
def admin_title_change(user_id, v):
@ -863,6 +891,7 @@ def admin_title_change(user_id, v):
@app.post("/ban_user/<id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_BAN'])
def ban_user(id, v):
@ -955,6 +984,7 @@ def ban_user(id, v):
@app.post("/agendaposter/<id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_AGENDAPOSTER'])
def agendaposter(id, v):
@ -1050,6 +1080,7 @@ def agendaposter(id, v):
@app.post("/unban_user/<id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_BAN'])
def unban_user(id, v):
@ -1095,6 +1126,7 @@ def unban_user(id, v):
@app.post("/mute_user/<int:user_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_BAN'])
def mute_user(v:User, user_id):
@ -1116,6 +1148,7 @@ def mute_user(v:User, user_id):
@app.post("/unmute_user/<int:user_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_BAN'])
def unmute_user(v:User, user_id):
@ -1135,6 +1168,7 @@ def unmute_user(v:User, user_id):
@app.post("/admin/progstack/post/<int:post_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['PROGSTACK'])
def progstack_post(post_id, v):
@ -1155,6 +1189,7 @@ def progstack_post(post_id, v):
@app.post("/admin/unprogstack/post/<int:post_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['PROGSTACK'])
def unprogstack_post(post_id, v):
@ -1173,6 +1208,7 @@ def unprogstack_post(post_id, v):
@app.post("/admin/progstack/comment/<int:comment_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['PROGSTACK'])
def progstack_comment(comment_id, v):
@ -1193,6 +1229,7 @@ def progstack_comment(comment_id, v):
@app.post("/admin/unprogstack/comment/<int:comment_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['PROGSTACK'])
def unprogstack_comment(comment_id, v):
@ -1211,6 +1248,7 @@ def unprogstack_comment(comment_id, v):
@app.post("/remove_post/<int:post_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def remove_post(post_id, v):
@ -1240,6 +1278,7 @@ def remove_post(post_id, v):
@app.post("/approve_post/<int:post_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def approve_post(post_id, v):
@ -1272,6 +1311,7 @@ def approve_post(post_id, v):
@app.post("/distinguish/<int:post_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_DISTINGUISH'])
def distinguish_post(post_id, v):
@ -1299,8 +1339,9 @@ def distinguish_post(post_id, v):
@app.post("/sticky/<int:post_id>")
@limiter.limit('1/second', scope=path)
@feature_required('PINS')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def sticky_post(post_id, v):
@ -1346,6 +1387,7 @@ def sticky_post(post_id, v):
@app.post("/unsticky/<int:post_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def unsticky_post(post_id, v):
@ -1376,6 +1418,7 @@ def unsticky_post(post_id, v):
@app.post("/sticky_comment/<int:cid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def sticky_comment(cid, v):
@ -1413,6 +1456,7 @@ def sticky_comment(cid, v):
@app.post("/unsticky_comment/<int:cid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def unsticky_comment(cid, v):
@ -1446,6 +1490,7 @@ def unsticky_comment(cid, v):
@app.post("/remove_comment/<int:c_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def remove_comment(c_id, v):
@ -1467,6 +1512,7 @@ def remove_comment(c_id, v):
@app.post("/approve_comment/<int:c_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def approve_comment(c_id, v):
@ -1494,6 +1540,7 @@ def approve_comment(c_id, v):
@app.post("/distinguish_comment/<int:c_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_DISTINGUISH'])
def admin_distinguish_comment(c_id, v):
@ -1520,6 +1567,7 @@ def admin_distinguish_comment(c_id, v):
else: return {"message": "Comment undistinguished!"}
@app.get("/admin/banned_domains/")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['DOMAINS_BAN'])
def admin_banned_domains(v):
@ -1530,6 +1578,7 @@ def admin_banned_domains(v):
@app.post("/admin/ban_domain")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['DOMAINS_BAN'])
def ban_domain(v):
@ -1562,6 +1611,7 @@ def ban_domain(v):
@app.post("/admin/unban_domain/<path:domain>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['DOMAINS_BAN'])
def unban_domain(v:User, domain):
@ -1582,6 +1632,7 @@ def unban_domain(v:User, domain):
@app.post("/admin/nuke_user")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def admin_nuke_user(v):
@ -1616,6 +1667,7 @@ def admin_nuke_user(v):
@app.post("/admin/unnuke_user")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
def admin_nunuke_user(v):
@ -1651,6 +1703,7 @@ def admin_nunuke_user(v):
@app.post("/blacklist/<int:user_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_BLACKLIST'])
def blacklist_user(user_id, v):
@ -1672,6 +1725,7 @@ def blacklist_user(user_id, v):
@app.post("/unblacklist/<int:user_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_BLACKLIST'])
def unblacklist_user(user_id, v):
@ -1693,6 +1747,7 @@ def unblacklist_user(user_id, v):
return {"message": f"@{user.username} has been unblacklisted from restricted holes!"}
@app.get('/admin/delete_media')
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['DELETE_MEDIA'])
def delete_media_get(v):
@ -1700,6 +1755,7 @@ def delete_media_get(v):
@app.post("/admin/delete_media")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['DELETE_MEDIA'])
def delete_media_post(v):

View File

@ -15,6 +15,7 @@ from files.__main__ import app, cache, limiter
ASSET_TYPES = (Marsey, HatDef)
@app.get("/submit/marseys")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def submit_marseys(v:User):
@ -34,6 +35,7 @@ def submit_marseys(v:User):
@app.post("/submit/marseys")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def submit_marsey(v:User):
@ -108,6 +110,7 @@ def verify_permissions_and_get_asset(cls, asset_type:str, v:User, name:str, make
@app.post("/admin/approve/marsey/<name>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'])
def approve_marsey(v, name):
@ -207,12 +210,14 @@ def remove_asset(cls, type_name:str, v:User, name:str) -> dict[str, str]:
@app.post("/remove/marsey/<name>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def remove_marsey(v:User, name):
return remove_asset(Marsey, "marsey", v, name)
@app.get("/submit/hats")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def submit_hats(v:User):
@ -224,6 +229,7 @@ def submit_hats(v:User):
@app.post("/submit/hats")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def submit_hat(v:User):
@ -359,12 +365,14 @@ def approve_hat(v, name):
@app.post("/remove/hat/<name>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def remove_hat(v:User, name):
return remove_asset(HatDef, 'hat', v, name)
@app.get("/admin/update/marseys")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['UPDATE_ASSETS'])
def update_marseys(v):
@ -384,6 +392,7 @@ def update_marseys(v):
@app.post("/admin/update/marseys")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['UPDATE_ASSETS'])
def update_marsey(v):
@ -435,6 +444,7 @@ def update_marsey(v):
return render_template("update_assets.html", v=v, msg=f"'{name}' updated successfully!", name=name, tags=tags, type="Marsey")
@app.get("/admin/update/hats")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['UPDATE_ASSETS'])
def update_hats(v):
@ -443,6 +453,7 @@ def update_hats(v):
@app.post("/admin/update/hats")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['UPDATE_ASSETS'])
def update_hat(v):

View File

@ -22,6 +22,7 @@ from .front import frontlist
@app.get("/shop/awards")
@app.get("/settings/shop")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def shop(v:User):
@ -129,6 +130,7 @@ def buy(v:User, award):
@app.post("/award/<thing_type>/<int:id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def award_thing(v, thing_type, id):

View File

@ -29,6 +29,7 @@ muted = cache.get(f'muted') or {}
messages = cache.get(f'messages') or {}
@app.get("/chat")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['CHAT'])
def chat(v):

View File

@ -28,6 +28,7 @@ WORDLE_COLOR_MAPPINGS = {-1: "🟥", 0: "🟨", 1: "🟩"}
@app.get("/post/<int:pid>/<anything>/<int:cid>")
@app.get("/h/<sub>/comment/<int:cid>")
@app.get("/h/<sub>/post/<int:pid>/<anything>/<int:cid>")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired_with_logingate
def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None):
@ -452,6 +453,7 @@ def edit_comment(cid, v):
@app.post("/delete/comment/<int:cid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def delete_comment(cid, v):
@ -474,6 +476,7 @@ def delete_comment(cid, v):
@app.post("/undelete/comment/<int:cid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def undelete_comment(cid, v):
@ -493,8 +496,9 @@ def undelete_comment(cid, v):
return {"message": "Comment undeleted!"}
@app.post("/pin_comment/<int:cid>")
@limiter.limit('1/second', scope=path)
@feature_required('PINS')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def pin_comment(cid, v):
@ -519,6 +523,7 @@ def pin_comment(cid, v):
@app.post("/unpin_comment/<int:cid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def unpin_comment(cid, v):
@ -542,6 +547,7 @@ def unpin_comment(cid, v):
@app.post("/save_comment/<int:cid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def save_comment(cid, v):
@ -559,6 +565,7 @@ def save_comment(cid, v):
@app.post("/unsave_comment/<int:cid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def unsave_comment(cid, v):
@ -595,6 +602,7 @@ def diff_words(answer, guess):
@app.post("/wordle/<int:cid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def handle_wordle_action(cid, v):
@ -626,8 +634,9 @@ def handle_wordle_action(cid, v):
@app.post("/toggle_comment_nsfw/<int:cid>")
@limiter.limit('1/second', scope=path)
@feature_required('NSFW_MARKING')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def toggle_comment_nsfw(cid, v):

View File

@ -3,9 +3,12 @@ from urllib.parse import quote, urlencode
from flask import redirect, render_template, request, session, g
from files.helpers.config.const import ERROR_MARSEYS, ERROR_MSGS, ERROR_TITLES, WERKZEUG_ERROR_DESCRIPTIONS, is_site_url
from files.helpers.config.const import *
from files.helpers.settings import get_setting
from files.__main__ import app
from files.routes.wrappers import path
from files.__main__ import app, limiter
# If you're adding an error, go here:
# https://github.com/pallets/werkzeug/blob/main/src/werkzeug/exceptions.py
@ -59,6 +62,8 @@ def error_500(e):
@app.post("/allow_nsfw")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
def allow_nsfw():
session["over_18"] = int(time.time()) + 3600
redir = request.values.get("redir", "/")

View File

@ -11,6 +11,7 @@ from files.__main__ import app
@app.get('/rss')
@app.get('/feed')
@app.get('/rss/<sort>/<t>')
@limiter.limit(DEFAULT_RATELIMIT)
def feeds_user(sort='hot', t='all'):
try: page = max(int(request.values.get("page", 1)), 1)

View File

@ -160,6 +160,7 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, filter_words='
@app.get("/random_post")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def random_post(v:User):
@ -173,6 +174,7 @@ def random_post(v:User):
@app.get("/random_user")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def random_user(v:User):
@ -212,6 +214,7 @@ def comment_idlist(v=None, page=1, sort="new", t="day", gt=0, lt=0, site=None):
return [x[0] for x in comments]
@app.get("/comments")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def all_comments(v:User):

View File

@ -7,6 +7,7 @@ from files.__main__ import app
@app.get("/giphy")
@app.get("/giphy<path>")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def giphy(v=None, path=None):

View File

@ -8,6 +8,7 @@ from files.routes.wrappers import *
from files.__main__ import app, limiter
@app.get("/ping_groups")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def ping_groups(v:User):
@ -16,6 +17,7 @@ def ping_groups(v:User):
@app.post("/create_group")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def create_group(v):
@ -54,6 +56,7 @@ def create_group(v):
@app.post("/!<group_name>/apply")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def join_group(v:User, group_name):
@ -69,6 +72,7 @@ def join_group(v:User, group_name):
@app.post("/!<group_name>/leave")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def leave_group(v:User, group_name):
@ -92,6 +96,7 @@ def leave_group(v:User, group_name):
@app.get("/!<group_name>")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def memberships(v:User, group_name):
@ -112,6 +117,7 @@ def memberships(v:User, group_name):
@app.post("/!<group_name>/<user_id>/approve")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def group_approve(v:User, group_name, user_id):
@ -134,6 +140,7 @@ def group_approve(v:User, group_name, user_id):
@app.post("/!<group_name>/<user_id>/reject")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def group_reject(v:User, group_name, user_id):

View File

@ -8,6 +8,7 @@ from files.routes.wrappers import *
from files.__main__ import app, limiter
@app.get("/shop/hats")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def hats(v:User):
@ -82,6 +83,7 @@ def buy_hat(v:User, hat_id):
@app.post("/equip_hat/<int:hat_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def equip_hat(v:User, hat_id):
@ -98,6 +100,7 @@ def equip_hat(v:User, hat_id):
@app.post("/unequip_hat/<int:hat_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def unequip_hat(v:User, hat_id):
@ -113,6 +116,7 @@ def unequip_hat(v:User, hat_id):
return {"message": f"'{hat.name}' unequipped!"}
@app.get("/hat_owners/<int:hat_id>")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def hat_owners(v:User, hat_id):

View File

@ -21,6 +21,7 @@ from files.routes.wrappers import *
NO_LOGIN_REDIRECT_URLS = ("/login", "/logout", "/signup", "/forgot", "/reset", "/reset_2fa", "/lost_2fa")
@app.get("/login")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired
def login_get(v:Optional[User]):
redir = request.values.get("redirect", "").strip().rstrip('?').lower()
@ -39,6 +40,7 @@ def login_deduct_when(resp):
@app.post("/login")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired
@limiter.limit("6/minute;10/day", deduct_when=login_deduct_when)
def login_post(v:Optional[User]):
@ -128,6 +130,7 @@ def on_login(account, redir=None):
@app.get("/me")
@app.get("/@me")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def me(v:User):
@ -137,6 +140,7 @@ def me(v:User):
@app.post("/logout")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def logout(v):
@ -147,6 +151,7 @@ def logout(v):
return {"message": "Logout successful!"}
@app.get("/signup")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired
def sign_up_get(v:Optional[User]):
if not get_setting('signups'):
@ -362,12 +367,14 @@ def sign_up_post(v:Optional[User]):
@app.get("/forgot")
@limiter.limit(DEFAULT_RATELIMIT)
def get_forgot():
return render_template("login/forgot_password.html")
@app.post("/forgot")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
def post_forgot():
username = request.values.get("username")
@ -403,6 +410,7 @@ def post_forgot():
@app.get("/reset")
@limiter.limit(DEFAULT_RATELIMIT)
def get_reset():
user_id = request.values.get("id")
timestamp = 0
@ -432,6 +440,7 @@ def get_reset():
@app.post("/reset")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired
def post_reset(v:Optional[User]):
if v: return redirect('/')
@ -470,6 +479,7 @@ def post_reset(v:Optional[User]):
message="Login normally to access your account.")
@app.get("/lost_2fa")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired
def lost_2fa(v:Optional[User]):
if v and not v.mfa_secret: abort(400, "You don't have 2FA enabled")
@ -515,6 +525,7 @@ def lost_2fa_post():
message="If the username, password, and email match, we will send you an email. Check your spam folder if you can't find it."), 202
@app.get("/reset_2fa")
@limiter.limit(DEFAULT_RATELIMIT)
def reset_2fa():
now=int(time.time())
t = request.values.get("t")

View File

@ -8,6 +8,7 @@ from files.__main__ import app, limiter
@app.post("/lottery/end")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['LOTTERY_ADMIN'])
def lottery_end(v):
@ -17,6 +18,7 @@ def lottery_end(v):
@app.post("/lottery/start")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['LOTTERY_ADMIN'])
def lottery_start(v):
@ -53,6 +55,7 @@ def lottery_active(v:User):
return {"message": "", "stats": {"user": v.lottery_stats, "lottery": lottery, "participants": participants}}
@app.get("/admin/lottery/participants")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['LOTTERY_VIEW_PARTICIPANTS'])
def lottery_admin(v):

View File

@ -11,6 +11,7 @@ from files.__main__ import app, limiter
@app.post("/verify_email")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def verify_email(v):
@ -19,6 +20,7 @@ def verify_email(v):
@app.get("/activate")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def activate(v:User):

View File

@ -12,6 +12,7 @@ from files.__main__ import app
@app.post("/clear")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def clear(v):
@ -26,6 +27,7 @@ def clear(v):
@app.get("/unread")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def unread(v):
@ -44,6 +46,7 @@ def unread(v):
@app.get("/notifications/modmail")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['VIEW_MODMAIL'])
def notifications_modmail(v):
@ -70,6 +73,7 @@ def notifications_modmail(v):
@app.get("/notifications/messages")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def notifications_messages(v:User):
@ -140,6 +144,7 @@ def notifications_messages(v:User):
@app.get("/notifications/posts")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def notifications_posts(v:User):
@ -183,6 +188,7 @@ def notifications_posts(v:User):
@app.get("/notifications/modactions")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def notifications_modactions(v:User):
@ -229,6 +235,7 @@ def notifications_modactions(v:User):
@app.get("/notifications/reddit")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def notifications_reddit(v:User):
@ -267,6 +274,7 @@ def notifications_reddit(v:User):
@app.get("/notifications")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def notifications(v:User):

View File

@ -8,6 +8,7 @@ from files.routes.wrappers import *
from files.__main__ import app, limiter
@app.get("/authorize")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def authorize_prompt(v:User):
@ -18,6 +19,7 @@ def authorize_prompt(v:User):
@app.post("/authorize")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def authorize(v):
@ -38,6 +40,7 @@ def authorize(v):
@app.post("/rescind/<int:aid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def rescind(v, aid):
@ -50,6 +53,7 @@ def rescind(v, aid):
@app.post("/api_keys")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def request_api_keys(v):
@ -91,6 +95,7 @@ def request_api_keys(v):
@app.post("/delete_app/<int:aid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def delete_oauth_app(v, aid):
@ -114,6 +119,7 @@ def delete_oauth_app(v, aid):
@app.post("/edit_app/<int:aid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def edit_oauth_app(v, aid):
@ -138,6 +144,7 @@ def edit_oauth_app(v, aid):
@app.post("/admin/app/approve/<int:aid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['APPS_MODERATION'])
def admin_app_approve(v, aid):
@ -175,6 +182,7 @@ def admin_app_approve(v, aid):
@app.post("/admin/app/revoke/<int:aid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['APPS_MODERATION'])
def admin_app_revoke(v, aid):
@ -201,6 +209,7 @@ def admin_app_revoke(v, aid):
@app.post("/admin/app/reject/<int:aid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['APPS_MODERATION'])
def admin_app_reject(v, aid):
@ -227,6 +236,7 @@ def admin_app_reject(v, aid):
@app.get("/admin/app/<int:aid>/posts")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['APPS_MODERATION'])
def admin_app_id_posts(v, aid):
@ -249,6 +259,7 @@ def admin_app_id_posts(v, aid):
)
@app.get("/admin/app/<int:aid>/comments")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['APPS_MODERATION'])
def admin_app_id_comments(v, aid):
@ -276,6 +287,7 @@ def admin_app_id_comments(v, aid):
@app.get("/admin/apps")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['APPS_MODERATION'])
def admin_apps_list(v):
@ -287,6 +299,7 @@ def admin_apps_list(v):
@app.post("/reroll/<int:aid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def reroll_oauth_tokens(aid, v):

View File

@ -7,6 +7,7 @@ from files.__main__ import app
@app.post("/vote/post/option/<int:option_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def vote_option(option_id, v):
@ -54,6 +55,7 @@ def vote_option(option_id, v):
return {"message": "Bet successful!"}
@app.get("/votes/post/option/<int:option_id>")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def option_votes(option_id, v):
@ -87,6 +89,7 @@ def option_votes(option_id, v):
@app.post("/vote/comment/option/<int:option_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def vote_option_comment(option_id, v):
@ -122,6 +125,7 @@ def vote_option_comment(option_id, v):
return "", 204
@app.get("/votes/comment/option/<int:option_id>")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def option_votes_comment(option_id, v):

View File

@ -34,6 +34,7 @@ titleheaders = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWe
@app.post("/publish/<int:pid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def publish(pid, v):
@ -66,6 +67,7 @@ def publish(pid, v):
@app.get("/submit")
@app.get("/h/<sub>/submit")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def submit_get(v:User, sub=None):
@ -80,6 +82,7 @@ def submit_get(v:User, sub=None):
@app.get("/post/<int:pid>/<anything>")
@app.get("/h/<sub>/post/<int:pid>")
@app.get("/h/<sub>/post/<int:pid>/<anything>")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired_with_logingate
def post_id(pid, anything=None, v=None, sub=None):
post = get_post(pid, v=v)
@ -174,6 +177,7 @@ def post_id(pid, anything=None, v=None, sub=None):
fart=get_setting('fart_mode'))
@app.get("/view_more/<int:pid>/<sort>/<offset>")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired_with_logingate
def view_more(v, pid, sort, offset):
post = get_post(pid, v=v)
@ -228,6 +232,7 @@ def view_more(v, pid, sort, offset):
@app.get("/more_comments/<int:cid>")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired_with_logingate
def more_comments(v, cid):
try: cid = int(cid)
@ -474,6 +479,7 @@ def thumbnail_thread(pid:int, vid:int):
@app.post("/is_repost")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
def is_repost():
not_a_repost = {'permalink': ''}
if not FEATURES['REPOST_DETECTION']:
@ -801,6 +807,7 @@ def submit_post(v:User, sub=None):
@app.post("/delete_post/<int:pid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def delete_post_pid(pid, v):
@ -828,6 +835,7 @@ def delete_post_pid(pid, v):
@app.post("/undelete_post/<int:pid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def undelete_post_pid(pid, v):
@ -849,8 +857,9 @@ def undelete_post_pid(pid, v):
@app.post("/mark_post_nsfw/<int:pid>")
@limiter.limit('1/second', scope=path)
@feature_required('NSFW_MARKING')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def mark_post_nsfw(pid, v):
@ -886,8 +895,9 @@ def mark_post_nsfw(pid, v):
return {"message": "Post has been marked as +18!"}
@app.post("/unmark_post_nsfw/<int:pid>")
@limiter.limit('1/second', scope=path)
@feature_required('NSFW_MARKING')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def unmark_post_nsfw(pid, v):
@ -924,6 +934,7 @@ def unmark_post_nsfw(pid, v):
@app.post("/save_post/<int:pid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def save_post(pid, v):
@ -940,6 +951,7 @@ def save_post(pid, v):
@app.post("/unsave_post/<int:pid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def unsave_post(pid, v):
@ -955,6 +967,7 @@ def unsave_post(pid, v):
@app.post("/pin/<int:post_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def pin_post(post_id, v):
@ -969,6 +982,7 @@ def pin_post(post_id, v):
return abort(404, "Post not found!")
@app.put("/post/<int:post_id>/new")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def set_new_sort(post_id:int, v:User):
@ -990,6 +1004,7 @@ def set_new_sort(post_id:int, v:User):
@app.delete("/post/<int:post_id>/new")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def unset_new_sort(post_id:int, v:User):

View File

@ -5,6 +5,7 @@ from files.classes.push_subscriptions import PushSubscription
@app.post("/push_subscribe")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def push_subscribe(v):

View File

@ -13,6 +13,7 @@ from files.__main__ import app, limiter, cache
@app.post("/report/post/<int:pid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def flag_post(pid, v):
@ -69,6 +70,7 @@ def flag_post(pid, v):
@app.post("/report/comment/<int:cid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def flag_comment(cid, v):

View File

@ -44,6 +44,7 @@ def searchparse(text):
return criteria
@app.get("/search/posts")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def searchposts(v:User):
@ -175,6 +176,7 @@ def searchposts(v:User):
)
@app.get("/search/comments")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def searchcomments(v:User):
@ -279,6 +281,7 @@ def searchcomments(v:User):
@app.get("/search/messages")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def searchmessages(v:User):
@ -358,6 +361,7 @@ def searchmessages(v:User):
return render_template("search_comments.html", v=v, query=query, total=total, page=page, comments=comments, sort=sort, t=t, next_exists=next_exists, standalone=True)
@app.get("/search/users")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def searchusers(v:User):

View File

@ -25,18 +25,21 @@ from files.__main__ import app, cache, limiter
@app.get("/settings")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings(v:User):
return redirect("/settings/personal")
@app.get("/settings/personal")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_personal(v:User):
return render_template("settings/personal.html", v=v, error=get_error(), msg=get_msg())
@app.delete('/settings/background')
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def remove_background(v):
@ -49,6 +52,7 @@ def remove_background(v):
@app.post('/settings/custom_background')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def upload_custom_background(v):
@ -73,6 +77,7 @@ def upload_custom_background(v):
@app.post('/settings/profile_background')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def upload_profile_background(v):
@ -93,6 +98,7 @@ def upload_profile_background(v):
return redirect(f'/@{v.username}')
@app.delete('/settings/profile_background')
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def delete_profile_background(v):
@ -103,6 +109,7 @@ def delete_profile_background(v):
@app.post("/settings/personal")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_personal_post(v):
@ -360,6 +367,7 @@ def settings_personal_post(v):
@app.post("/settings/filters")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def filters(v:User):
@ -388,6 +396,7 @@ def set_color(v:User, attr:str, color:Optional[str]):
@app.post("/settings/namecolor")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def namecolor(v):
@ -395,6 +404,7 @@ def namecolor(v):
@app.post("/settings/themecolor")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def themecolor(v):
@ -402,6 +412,7 @@ def themecolor(v):
@app.post("/settings/titlecolor")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def titlecolor(v):
@ -409,6 +420,7 @@ def titlecolor(v):
@app.post("/settings/verifiedcolor")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def verifiedcolor(v):
@ -417,6 +429,7 @@ def verifiedcolor(v):
@app.post("/settings/security")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_security_post(v):
@ -491,6 +504,7 @@ def settings_security_post(v):
@app.post("/settings/log_out_all_others")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_log_out_others(v):
@ -507,6 +521,7 @@ def settings_log_out_others(v):
@app.post("/settings/images/profile")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_images_profile(v):
@ -544,8 +559,9 @@ def settings_images_profile(v):
@app.post("/settings/images/banner")
@limiter.limit('1/second', scope=path)
@feature_required('USERS_PROFILE_BANNER')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_images_banner(v):
@ -566,6 +582,7 @@ def settings_images_banner(v):
return redirect("/settings/personal?msg=Banner successfully updated!")
@app.get("/settings/css")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_css_get(v:User):
@ -573,6 +590,7 @@ def settings_css_get(v:User):
@app.post("/settings/css")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_css(v):
@ -585,6 +603,7 @@ def settings_css(v):
@app.post("/settings/profilecss")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_profilecss(v):
@ -597,6 +616,7 @@ def settings_profilecss(v):
return redirect("/settings/css?msg=Profile CSS successfully updated!")
@app.get("/settings/security")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_security(v:User):
@ -638,6 +658,7 @@ def settings_block_user(v):
@app.post("/settings/unblock")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_unblock_user(v):
@ -651,12 +672,14 @@ def settings_unblock_user(v):
return {"message": f"@{user.username} unblocked successfully!"}
@app.get("/settings/apps")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_apps(v:User):
return render_template("settings/apps.html", v=v)
@app.get("/settings/advanced")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_advanced_get(v:User):
@ -664,6 +687,7 @@ def settings_advanced_get(v:User):
@app.post("/settings/name_change")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def settings_name_change(v):
@ -701,8 +725,8 @@ def settings_name_change(v):
return redirect("/settings/personal?msg=Name successfully changed!")
@app.post("/settings/song_change_mp3")
@limiter.limit('1/second', scope=path)
@feature_required('USERS_PROFILE_SONG')
@limiter.limit('1/second', scope=path)
@limiter.limit("10/day")
@limiter.limit("10/day", key_func=get_ID)
@auth_required
@ -766,8 +790,8 @@ def _change_song_youtube(vid, id):
@app.post("/settings/song_change")
@limiter.limit('1/second', scope=path)
@feature_required('USERS_PROFILE_SONG')
@limiter.limit('1/second', scope=path)
@limiter.limit("10/day")
@limiter.limit("10/day", key_func=get_ID)
@auth_required
@ -820,6 +844,7 @@ def settings_song_change(v):
@app.post("/settings/title_change")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_title_change(v):
@ -847,8 +872,9 @@ def settings_title_change(v):
@app.post("/settings/pronouns_change")
@limiter.limit('1/second', scope=path)
@feature_required('PRONOUNS')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_pronouns_change(v):
@ -875,6 +901,7 @@ def settings_pronouns_change(v):
@app.post("/settings/checkmark_text")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_checkmark_text(v):
@ -889,6 +916,7 @@ def settings_checkmark_text(v):
if IS_FISTMAS():
@app.post("/events/fistmas2022/darkmode")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def event_darkmode(v):

View File

@ -1,8 +1,10 @@
from flask import g, render_template
from files.helpers.get import get_accounts_dict
from files.helpers.config.const import *
from files.routes.wrappers import auth_required
from files.__main__ import app, cache
from files.routes.wrappers import *
from files.__main__ import app, cache, limiter
_special_leaderboard_query = """
WITH bet_options AS (
@ -80,6 +82,8 @@ def _special_leaderboard_get():
@app.get('/events/worldcup2022/leaderboard')
@app.get('/special/worldcup2022/leaderboard')
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def get_leaderboard(v):
if SITE_NAME != 'rDrama':

View File

@ -19,11 +19,13 @@ from files.__main__ import app, cache, limiter
@app.get("/r/drama/comments/<int:id>/<title>")
@app.get("/r/Drama/comments/<int:id>/<title>")
@limiter.limit(DEFAULT_RATELIMIT)
def rdrama(id, title):
id = ''.join(f'{x}/' for x in id)
return redirect(f'/archives/drama/comments/{id}{title}.html')
@app.get("/r/<subreddit>")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired
def subreddit(subreddit, v):
reddit = v.reddit if v else "old.reddit.com"
@ -31,6 +33,7 @@ def subreddit(subreddit, v):
@app.get("/reddit/<subreddit>/comments/<path:path>")
@app.get("/r/<subreddit>/comments/<path:path>")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired
def reddit_post(subreddit, v, path):
post_id = path.rsplit("/", 1)[0].replace('/', '')
@ -39,6 +42,7 @@ def reddit_post(subreddit, v, path):
@app.get("/marseys")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def marseys(v:User):
@ -58,6 +62,7 @@ def marseys(v:User):
return render_template("marseys.html", v=v, marseys=marseys)
@app.get("/emojis")
@limiter.limit(DEFAULT_RATELIMIT)
def emoji_list():
return get_emojis(g.db)
@ -80,12 +85,14 @@ def get_emojis(db:scoped_session):
return emojis
@app.get('/sidebar')
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired
def sidebar(v:Optional[User]):
return render_template('sidebar.html', v=v)
@app.get("/stats")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def participation_stats(v:User):
@ -94,16 +101,19 @@ def participation_stats(v:User):
return render_template("stats.html", v=v, title="Content Statistics", data=stats)
@app.get("/chart")
@limiter.limit(DEFAULT_RATELIMIT)
def chart():
return redirect('/weekly_chart')
@app.get("/weekly_chart")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def weekly_chart(v:User):
return send_file(statshelper.chart_path(kind="weekly", site=SITE))
@app.get("/daily_chart")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def daily_chart(v:User):
@ -111,6 +121,7 @@ def daily_chart(v:User):
@app.get("/patrons")
@app.get("/paypigs")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['VIEW_PATRONS'])
def patrons(v):
@ -120,6 +131,7 @@ def patrons(v):
@app.get("/admins")
@app.get("/badmins")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def admins(v:User):
@ -128,6 +140,7 @@ def admins(v:User):
@app.get("/log")
@app.get("/modlog")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def log(v:User):
@ -176,6 +189,7 @@ def log(v:User):
return render_template("log.html", v=v, admins=admins, types=types, admin=admin, type=kind, actions=actions, next_exists=next_exists, page=page, single_user_url='admin')
@app.get("/log/<int:id>")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def log_item(id, v):
@ -198,6 +212,7 @@ def log_item(id, v):
return render_template("log.html", v=v, actions=[action], next_exists=False, page=1, action=action, admins=admins, types=types, single_user_url='admin')
@app.get("/directory")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def static_megathread_index(v:User):
@ -211,6 +226,7 @@ def static_megathread_index(v:User):
return render_template("megathread_index.html", v=v, emojis_hash=emojis_hash, emojis_count=emojis_count, emojis_size=emojis_size)
@app.get("/api")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def api(v):
@ -222,6 +238,7 @@ def api(v):
@app.get("/press")
@app.get("/media")
@app.get("/admin/chat")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired
def contact(v:Optional[User]):
return render_template("contact.html", v=v, msg=get_msg())
@ -269,6 +286,7 @@ def submit_contact(v):
return redirect("/contact?msg=Your message has been sent to the admins!")
@app.get('/archives')
@limiter.limit(DEFAULT_RATELIMIT)
def archivesindex():
return redirect("/archives/index.html")
@ -288,6 +306,7 @@ def badge_list(site):
@app.get("/badges")
@feature_required('BADGES')
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def badges(v:User):
@ -295,6 +314,7 @@ def badges(v:User):
return render_template("badges.html", v=v, badges=badges, counts=counts)
@app.get("/blocks")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@admin_level_required(PERMS['USER_BLOCKS_VISIBLE'])
def blocks(v):
@ -311,23 +331,27 @@ def blocks(v):
return render_template("blocks.html", v=v, users=users, targets=targets)
@app.get("/formatting")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def formatting(v:User):
return render_template("formatting.html", v=v)
@app.get("/app")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired
def mobile_app(v:Optional[User]):
return render_template("app.html", v=v)
@app.post("/dismiss_mobile_tip")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
def dismiss_mobile_tip():
session["tooltip_last_dismissed"] = int(time.time())
return "", 204
@app.get("/transfers/<int:id>")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def transfers_id(id, v):
@ -342,6 +366,7 @@ def transfers_id(id, v):
return render_template("transfers.html", v=v, page=1, comments=[transfer], standalone=True, next_exists=False)
@app.get("/transfers")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def transfers(v:User):
@ -365,6 +390,7 @@ if not os.path.exists(f'files/templates/donate_{SITE_NAME}.html'):
copyfile('files/templates/donate_rDrama.html', f'files/templates/donate_{SITE_NAME}.html')
@app.get('/donate')
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired_with_logingate
def donate(v):
return render_template(f'donate_{SITE_NAME}.html', v=v)

View File

@ -9,6 +9,7 @@ from files.__main__ import app, cache, limiter
@app.post("/exile/post/<int:pid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def exile_post(v:User, pid):
@ -42,6 +43,7 @@ def exile_post(v:User, pid):
@app.post("/exile/comment/<int:cid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def exile_comment(v:User, cid):
@ -75,6 +77,7 @@ def exile_comment(v:User, cid):
@app.post("/h/<sub>/unexile/<int:uid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def unexile(v:User, sub, uid):
@ -105,6 +108,7 @@ def unexile(v:User, sub, uid):
@app.post("/h/<sub>/block")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def block_sub(v:User, sub):
@ -118,6 +122,7 @@ def block_sub(v:User, sub):
@app.post("/h/<sub>/unblock")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def unblock_sub(v:User, sub):
@ -135,6 +140,7 @@ def unblock_sub(v:User, sub):
@app.post("/h/<sub>/subscribe")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def subscribe_sub(v:User, sub):
@ -148,6 +154,7 @@ def subscribe_sub(v:User, sub):
@app.post("/h/<sub>/unsubscribe")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def unsubscribe_sub(v:User, sub):
@ -160,6 +167,7 @@ def unsubscribe_sub(v:User, sub):
@app.post("/h/<sub>/follow")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def follow_sub(v:User, sub):
@ -176,6 +184,7 @@ def follow_sub(v:User, sub):
@app.post("/h/<sub>/unfollow")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def unfollow_sub(v:User, sub):
@ -188,6 +197,7 @@ def unfollow_sub(v:User, sub):
return {"message": f"/h/{sub} unfollowed successfully!"}
@app.get("/h/<sub>/mods")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def mods(v:User, sub):
@ -200,6 +210,7 @@ def mods(v:User, sub):
@app.get("/h/<sub>/exilees")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def sub_exilees(v:User, sub):
@ -214,6 +225,7 @@ def sub_exilees(v:User, sub):
@app.get("/h/<sub>/blockers")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def sub_blockers(v:User, sub):
@ -229,6 +241,7 @@ def sub_blockers(v:User, sub):
@app.get("/h/<sub>/followers")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def sub_followers(v:User, sub):
@ -284,6 +297,7 @@ def add_mod(v:User, sub):
@app.post("/h/<sub>/remove_mod")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def remove_mod(v:User, sub):
@ -324,6 +338,7 @@ def remove_mod(v:User, sub):
return {"message": f"@{user.username} has been removed as a mod!"}
@app.get("/create_hole")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def create_sub(v):
@ -334,6 +349,7 @@ def create_sub(v):
@app.post("/create_hole")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def create_sub2(v):
@ -369,6 +385,7 @@ def create_sub2(v):
@app.post("/kick/<int:pid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def kick(v:User, pid):
@ -401,6 +418,7 @@ def kick(v:User, pid):
return {"message": f"Post kicked from /h/{old} successfully!"}
@app.get('/h/<sub>/settings')
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def sub_settings(v:User, sub):
@ -411,6 +429,7 @@ def sub_settings(v:User, sub):
@app.post('/h/<sub>/sidebar')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def post_sub_sidebar(v:User, sub):
@ -436,6 +455,7 @@ def post_sub_sidebar(v:User, sub):
@app.post('/h/<sub>/css')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def post_sub_css(v:User, sub):
@ -467,6 +487,7 @@ def post_sub_css(v:User, sub):
return redirect(f'/h/{sub}/settings')
@app.get("/h/<sub>/css")
@limiter.limit(DEFAULT_RATELIMIT)
def get_sub_css(sub):
sub = g.db.query(Sub.css).filter_by(name=sub.strip().lower()).one_or_none()
if not sub: abort(404)
@ -628,6 +649,7 @@ def sub_marsey(v:User, sub):
@app.get("/flairs")
@app.get("/holes")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def subs(v:User):
@ -637,6 +659,7 @@ def subs(v:User):
@app.post("/hole_pin/<int:pid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def hole_pin(v:User, pid):
@ -667,6 +690,7 @@ def hole_pin(v:User, pid):
@app.post("/hole_unpin/<int:pid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def hole_unpin(v:User, pid):
@ -698,6 +722,7 @@ def hole_unpin(v:User, pid):
@app.post('/h/<sub>/stealth')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def sub_stealth(v:User, sub):
@ -730,8 +755,9 @@ def sub_stealth(v:User, sub):
@app.post("/mod_pin/<int:cid>")
@limiter.limit('1/second', scope=path)
@feature_required('PINS')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def mod_pin(cid, v):
@ -761,6 +787,7 @@ def mod_pin(cid, v):
@app.post("/unmod_pin/<int:cid>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def mod_unpin(cid, v):
@ -789,6 +816,7 @@ def mod_unpin(cid, v):
@app.get("/h/<sub>/log")
@app.get("/h/<sub>/modlog")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def hole_log(v:User, sub):
@ -831,6 +859,7 @@ def hole_log(v:User, sub):
return render_template("log.html", v=v, admins=mods, types=types, admin=mod, type=kind, actions=actions, next_exists=next_exists, page=page, sub=sub, single_user_url='mod')
@app.get("/h/<sub>/log/<int:id>")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def hole_log_item(id, v, sub):

View File

@ -55,6 +55,7 @@ def upvoters_downvoters(v, username, uid, cls, vote_cls, vote_dir, template, sta
return render_template(template, next_exists=next_exists, listing=listing, page=page, v=v, standalone=standalone)
@app.get("/@<username>/upvoters/<int:uid>/posts")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def upvoters_posts(v:User, username, uid):
@ -62,6 +63,7 @@ def upvoters_posts(v:User, username, uid):
@app.get("/@<username>/upvoters/<int:uid>/comments")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def upvoters_comments(v:User, username, uid):
@ -69,6 +71,7 @@ def upvoters_comments(v:User, username, uid):
@app.get("/@<username>/downvoters/<int:uid>/posts")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def downvoters_posts(v:User, username, uid):
@ -76,6 +79,7 @@ def downvoters_posts(v:User, username, uid):
@app.get("/@<username>/downvoters/<int:uid>/comments")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def downvoters_comments(v:User, username, uid):
@ -110,6 +114,7 @@ def upvoting_downvoting(v, username, uid, cls, vote_cls, vote_dir, template, sta
return render_template(template, next_exists=next_exists, listing=listing, page=page, v=v, standalone=standalone)
@app.get("/@<username>/upvoting/<int:uid>/posts")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def upvoting_posts(v:User, username, uid):
@ -117,6 +122,7 @@ def upvoting_posts(v:User, username, uid):
@app.get("/@<username>/upvoting/<int:uid>/comments")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def upvoting_comments(v:User, username, uid):
@ -124,6 +130,7 @@ def upvoting_comments(v:User, username, uid):
@app.get("/@<username>/downvoting/<int:uid>/posts")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def downvoting_posts(v:User, username, uid):
@ -131,6 +138,7 @@ def downvoting_posts(v:User, username, uid):
@app.get("/@<username>/downvoting/<int:uid>/comments")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def downvoting_comments(v:User, username, uid):
@ -165,6 +173,7 @@ def user_voted(v, username, cls, vote_cls, template, standalone):
return render_template(template, next_exists=next_exists, listing=listing, page=page, v=v, standalone=standalone)
@app.get("/@<username>/voted/posts")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def user_voted_posts(v:User, username):
@ -172,12 +181,14 @@ def user_voted_posts(v:User, username):
@app.get("/@<username>/voted/comments")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def user_voted_comments(v:User, username):
return user_voted(v, username, Comment, CommentVote, "userpage/voted_comments.html", True)
@app.get("/banned")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def banned(v:User):
@ -191,6 +202,7 @@ def banned(v:User):
return render_template("banned.html", v=v, users=users)
@app.get("/grassed")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def grassed(v:User):
@ -204,6 +216,7 @@ def grassed(v:User):
return render_template("grassed.html", v=v, users=users)
@app.get("/chuds")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def chuds(v:User):
@ -219,7 +232,7 @@ def chuds(v:User):
def all_upvoters_downvoters(v:User, username:str, vote_dir:int, is_who_simps_hates:bool):
if username == 'Snappy':
abort(403, "For performance reasons, you can't see Snappy statistics!")
abort(403, "For performance reasons, you can't see Snappy's statistics!")
vote_str = 'votes'
simps_haters = 'voters'
vote_name = 'Neutral'
@ -273,32 +286,36 @@ def all_upvoters_downvoters(v:User, username:str, vote_dir:int, is_who_simps_hat
return render_template("userpage/voters.html", v=v, users=users, pos=pos, name=vote_name, name2=name2, total=total, page=page, next_exists=next_exists)
@app.get("/@<username>/upvoters")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def upvoters(v:User, username:str):
return all_upvoters_downvoters(v, username, 1, False)
@app.get("/@<username>/downvoters")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def downvoters(v:User, username:str):
return all_upvoters_downvoters(v, username, -1, False)
@app.get("/@<username>/upvoting")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def upvoting(v:User, username:str):
return all_upvoters_downvoters(v, username, 1, True)
@app.get("/@<username>/downvoting")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def downvoting(v:User, username:str):
return all_upvoters_downvoters(v, username, -1, True)
@app.post("/@<username>/suicide")
@limiter.limit('1/second', scope=path)
@feature_required('USERS_SUICIDE')
@limiter.limit('1/second', scope=path)
@limiter.limit("5/day")
@limiter.limit("5/day", key_func=get_ID)
@auth_required
@ -311,6 +328,7 @@ def suicide(v:User, username:str):
@app.get("/@<username>/coins")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def get_coins(v:User, username:str):
@ -359,20 +377,23 @@ def transfer_currency(v:User, username:str, currency_name:Literal['coins', 'mars
@app.post("/@<username>/transfer_coins")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def transfer_coins(v:User, username:str):
return transfer_currency(v, username, 'coins', True)
@app.post("/@<username>/transfer_bux")
@limiter.limit('1/second', scope=path)
@feature_required('MARSEYBUX')
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@is_not_permabanned
def transfer_bux(v:User, username:str):
return transfer_currency(v, username, 'marseybux', False)
@app.get("/leaderboard")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def leaderboard(v:User):
@ -403,6 +424,7 @@ def leaderboard(v:User):
return render_template("leaderboard.html", v=v, leaderboards=leaderboards)
@app.get("/<int:id>/css")
@limiter.limit(DEFAULT_RATELIMIT)
def get_css(id):
try: id = int(id)
except: abort(404)
@ -426,6 +448,7 @@ def get_css(id):
return resp
@app.get("/<int:id>/profilecss")
@limiter.limit(DEFAULT_RATELIMIT)
def get_profilecss(id):
try: id = int(id)
except: abort(404)
@ -447,6 +470,7 @@ def get_profilecss(id):
return resp
@app.get("/@<username>/song")
@limiter.limit(DEFAULT_RATELIMIT)
def usersong(username:str):
user = get_user(username)
if user.song: return redirect(f"/songs/{user.song}.mp3")
@ -454,6 +478,7 @@ def usersong(username:str):
@app.post("/subscribe/<int:post_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def subscribe(v, post_id):
@ -465,6 +490,7 @@ def subscribe(v, post_id):
@app.post("/unsubscribe/<int:post_id>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def unsubscribe(v, post_id):
@ -627,6 +653,7 @@ def messagereply(v:User):
return {"comment": render_template("comments.html", v=v, comments=[c])}
@app.get("/2faqr/<secret>")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def mfa_qr(v:User, secret:str):
@ -670,17 +697,20 @@ def is_available(name:str):
return {name: True}
@app.get("/id/<int:id>")
@limiter.limit(DEFAULT_RATELIMIT)
def user_id(id):
user = get_account(id)
return redirect(user.url)
@app.get("/u/<username>")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def redditor_moment_redirect(v:User, username:str):
return redirect(f"/@{username}")
@app.get("/@<username>/followers")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def followers(v:User, username:str):
@ -703,6 +733,7 @@ def followers(v:User, username:str):
return render_template("userpage/followers.html", v=v, u=u, users=users, page=page, next_exists=next_exists)
@app.get("/@<username>/blockers")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def blockers(v:User, username:str):
@ -722,6 +753,7 @@ def blockers(v:User, username:str):
return render_template("userpage/blockers.html", v=v, u=u, users=users, page=page, next_exists=next_exists)
@app.get("/@<username>/following")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def following(v:User, username:str):
@ -743,6 +775,7 @@ def following(v:User, username:str):
return render_template("userpage/following.html", v=v, u=u, users=users, page=page, next_exists=next_exists)
@app.get("/@<username>/views")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def visitors(v:User, username:str):
@ -771,6 +804,7 @@ def userpagelisting(user:User, site=None, v=None, page:int=1, sort="new", t="all
@app.get("/@<username>")
@app.get("/@<username>.json")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired_with_logingate
def u_username_wall(v:Optional[User], username:str):
u = get_user(username, v=v, include_blocks=True, include_shadowbanned=False)
@ -824,6 +858,7 @@ def u_username_wall(v:Optional[User], username:str):
@app.get("/@<username>/wall/comment/<int:cid>")
@app.get("/@<username>/wall/comment/<int:cid>.json")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired_with_logingate
def u_username_wall_comment(v:User, username:str, cid):
comment = get_comment(cid, v=v)
@ -875,6 +910,7 @@ def u_username_wall_comment(v:User, username:str, cid):
@app.get("/@<username>/posts")
@app.get("/@<username>/posts.json")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired_with_logingate
def u_username(v:Optional[User], username:str):
u = get_user(username, v=v, include_blocks=True, include_shadowbanned=False)
@ -952,6 +988,7 @@ def u_username(v:Optional[User], username:str):
@app.get("/@<username>/comments")
@app.get("/@<username>/comments.json")
@limiter.limit(DEFAULT_RATELIMIT)
@auth_desired_with_logingate
def u_username_comments(username, v=None):
u = get_user(username, v=v, include_blocks=True, include_shadowbanned=False)
@ -1020,6 +1057,7 @@ def u_username_comments(username, v=None):
@app.get("/@<username>/info")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def u_username_info(username, v=None):
@ -1034,6 +1072,7 @@ def u_username_info(username, v=None):
return user.json
@app.get("/<int:id>/info")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def u_user_id_info(id, v=None):
@ -1049,6 +1088,7 @@ def u_user_id_info(id, v=None):
@app.post("/follow/<username>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def follow_user(username, v):
@ -1076,6 +1116,7 @@ def follow_user(username, v):
@app.post("/unfollow/<username>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def unfollow_user(username, v):
@ -1104,6 +1145,7 @@ def unfollow_user(username, v):
@app.post("/remove_follow/<username>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def remove_follow(username, v):
@ -1168,6 +1210,7 @@ def get_saves_and_subscribes(v, template, relationship_cls, page:int, standalone
return render_template(template, u=v, v=v, listing=listing, page=page, next_exists=next_exists, standalone=standalone)
@app.get("/@<username>/saved/posts")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def saved_posts(v:User, username):
@ -1177,6 +1220,7 @@ def saved_posts(v:User, username):
return get_saves_and_subscribes(v, "userpage/submissions.html", SaveRelationship, page, False)
@app.get("/@<username>/saved/comments")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def saved_comments(v:User, username):
@ -1186,6 +1230,7 @@ def saved_comments(v:User, username):
return get_saves_and_subscribes(v, "userpage/comments.html", CommentSaveRelationship, page, True)
@app.get("/@<username>/subscribed/posts")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def subscribed_posts(v:User, username):
@ -1196,6 +1241,7 @@ def subscribed_posts(v:User, username):
@app.post("/fp/<fp>")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def fp(v:User, fp):
@ -1219,6 +1265,7 @@ def fp(v:User, fp):
return '', 204
@app.get("/toggle_pins/<sort>")
@limiter.limit(DEFAULT_RATELIMIT)
def toggle_pins(sort):
if sort == 'hot': default = True
else: default = False
@ -1232,6 +1279,7 @@ def toggle_pins(sort):
@app.get("/toggle_holes")
@limiter.limit(DEFAULT_RATELIMIT)
def toggle_holes():
if SITE_NAME == 'WPD':
abort(404)
@ -1245,6 +1293,7 @@ def toggle_holes():
@app.get("/badge_owners/<int:bid>")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def bid_list(v:User, bid):
@ -1322,6 +1371,7 @@ def claim_rewards_all_users():
KOFI_TOKEN = environ.get("KOFI_TOKEN", "").strip()
if KOFI_TOKEN:
@app.post("/kofi")
@limiter.limit(DEFAULT_RATELIMIT)
def kofi():
data = json.loads(request.values['data'])
verification_token = data['verification_token']
@ -1353,6 +1403,7 @@ if KOFI_TOKEN:
@app.post("/gumroad")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
def gumroad():
data = request.values
ip = request.headers.get('CF-Connecting-IP')
@ -1385,6 +1436,7 @@ def gumroad():
@app.post("/settings/claim_rewards")
@limiter.limit('1/second', scope=path)
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def settings_claim_rewards(v:User):
@ -1401,6 +1453,7 @@ def settings_claim_rewards(v:User):
return {"message": f"{patron} rewards claimed!"}
@app.get("/users")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def users_list(v):

View File

@ -8,6 +8,7 @@ from files.routes.routehelpers import get_alt_graph
from math import floor
@app.get("/votes/<link>")
@limiter.limit(DEFAULT_RATELIMIT)
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
@auth_required
def vote_info_get(v, link):
@ -198,7 +199,6 @@ def vote_post_comment(target_id, new, v, cls, vote_cls):
@limiter.limit("60/minute;1000/hour;2000/day")
@limiter.limit("60/minute;1000/hour;2000/day", key_func=get_ID)
@is_not_permabanned
@limiter.limit("1/second", key_func=lambda:f'{g.v.id}-{request.full_path}')
def vote_post(post_id, new, v):
return vote_post_comment(post_id, new, v, Submission, Vote)
@ -207,6 +207,5 @@ def vote_post(post_id, new, v):
@limiter.limit("60/minute;1000/hour;2000/day")
@limiter.limit("60/minute;1000/hour;2000/day", key_func=get_ID)
@is_not_permabanned
@limiter.limit("1/second", key_func=lambda:f'{g.v.id}-{request.full_path}')
def vote_comment(comment_id, new, v):
return vote_post_comment(comment_id, new, v, Comment, CommentVote)