From ad9b8cedb4dace41215ebb655224b65afd3c6cc2 Mon Sep 17 00:00:00 2001 From: Jonathan Wu Date: Fri, 15 Dec 2023 11:07:52 -0500 Subject: [PATCH] Fix more races --- src/views/admin.py | 15 ++++++++++++--- src/views/contest.py | 12 ++++++++++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/views/admin.py b/src/views/admin.py index 4eb66c0..d2cccc5 100644 --- a/src/views/admin.py +++ b/src/views/admin.py @@ -178,8 +178,10 @@ def update_perms(): flash("Must provide user ID", "danger") return redirect("/admin/users") + db.execute("BEGIN") user = db.execute("SELECT * FROM users WHERE id=:id", id=user_id) if len(user) == 0: + db.execute("COMMIT") flash("That user doesn't exist", "danger") return redirect("/admin/users") user_id = int(user_id) @@ -192,6 +194,7 @@ def update_perms(): perms_add = new_perms - cur_perms perms_remove = cur_perms - new_perms if not perms_add and not perms_remove: + db.execute("COMMIT") flash("No perms were updated", "warning") return redirect("/admin/users") @@ -202,18 +205,21 @@ def update_perms(): # Permission checks for sensitive permissions if check_perm(["ADMIN", "SUPERADMIN"], perms_remove) and not check_perm(["SUPERADMIN"]): + db.execute("COMMIT") flash("Only the super-admin can revoke admin status", "danger") return redirect("/admin/users") if check_perm(["SUPERADMIN"], perms_add) and not check_perm(["SUPERADMIN"]): + db.execute("COMMIT") flash("Only the super-admin can create super-admins", "danger") return redirect("/admin/users") # Update permissions for perm in perms_add: db.execute("INSERT INTO user_perms(user_id, perm_id) VALUES(?, ?)", user_id, perm) - for perm in perms_remove: - db.execute("DELETE FROM user_perms WHERE user_id=? AND perm_id=?", user_id, perm) + db.execute("DELETE FROM user_perms WHERE user_id=? AND perm_id IN (?)", + user_id, list(perms_remove)) + db.execute("COMMIT") # Flash and log message msg = f"Permissions changed for user #{user_id} ({user[0]['username']}). " @@ -261,7 +267,10 @@ def delete_announcement(): if not aid: return "Must provide announcement ID", 400 - db.execute("DELETE FROM announcements WHERE id=:id", id=aid) + r = db.execute("DELETE FROM announcements WHERE id=?", aid) + if r == 0: + flash("That announcement doesn't exist", "warning") + return redirect("/") os.remove('metadata/announcements/' + aid + '.md') logger.info((f"User #{session['user_id']} ({session['username']}) deleted " diff --git a/src/views/contest.py b/src/views/contest.py index 2f0ea41..9561aa7 100644 --- a/src/views/contest.py +++ b/src/views/contest.py @@ -464,10 +464,14 @@ def contest_hide(contest_id): flash("No user ID specified, please try again", "danger") return redirect("/contest/" + contest_id + "/scoreboard") - db.execute( + r = db.execute( "UPDATE contest_users SET hidden=1 WHERE user_id=:uid AND contest_id=:cid", uid=user_id, cid=contest_id) + if r == 0: + flash("That user isn't present in this contest", "warning") + return redirect("/contest/" + contest_id + "/scoreboard") + logger.info((f"User #{user_id} hidden from contest {contest_id} by " f"user #{session['user_id']} ({session['username']})"), extra={"section": "contest"}) @@ -486,10 +490,14 @@ def contest_unhide(contest_id): flash("No user ID specified, please try again", "danger") return redirect("/contest/" + contest_id + "/scoreboard") - db.execute( + r = db.execute( "UPDATE contest_users SET hidden=0 WHERE user_id=:uid AND contest_id=:cid", uid=user_id, cid=contest_id) + if r == 0: + flash("That user isn't present in this contest", "warning") + return redirect("/contest/" + contest_id + "/scoreboard") + logger.info((f"User #{user_id} unhidden from contest {contest_id} by " f"user #{session['user_id']} ({session['username']})"), extra={"section": "contest"})