Skip to content

Commit e97bee8

Browse files
authored
Allow zero submission rate limits (#491)
1 parent a935653 commit e97bee8

4 files changed

Lines changed: 42 additions & 4 deletions

File tree

src/kernelbot/api/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,8 +1131,8 @@ async def admin_set_rate_limit(
11311131
if mode_category not in ("test", "leaderboard"):
11321132
raise HTTPException(status_code=400, detail="mode_category must be 'test' or 'leaderboard'")
11331133
max_per_hour = payload.get("max_submissions_per_hour")
1134-
if not isinstance(max_per_hour, int) or max_per_hour < 1:
1135-
raise HTTPException(status_code=400, detail="max_submissions_per_hour must be a positive integer")
1134+
if not isinstance(max_per_hour, int) or max_per_hour < 0:
1135+
raise HTTPException(status_code=400, detail="max_submissions_per_hour must be a non-negative integer")
11361136
try:
11371137
with db_context as db:
11381138
result = db.set_rate_limit(leaderboard_name, mode_category, max_per_hour)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
Allow zero-submission rate limits.
3+
"""
4+
5+
from yoyo import step
6+
7+
__depends__ = {"20260318_01_ban-user"}
8+
9+
steps = [
10+
step(
11+
"""
12+
ALTER TABLE leaderboard.rate_limit
13+
DROP CONSTRAINT rate_limit_max_submissions_per_hour_check;
14+
15+
ALTER TABLE leaderboard.rate_limit
16+
ADD CONSTRAINT rate_limit_max_submissions_per_hour_check
17+
CHECK (max_submissions_per_hour >= 0);
18+
""",
19+
"""
20+
ALTER TABLE leaderboard.rate_limit
21+
DROP CONSTRAINT rate_limit_max_submissions_per_hour_check;
22+
23+
ALTER TABLE leaderboard.rate_limit
24+
ADD CONSTRAINT rate_limit_max_submissions_per_hour_check
25+
CHECK (max_submissions_per_hour > 0);
26+
""",
27+
)
28+
]

tests/test_admin_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -800,11 +800,11 @@ def test_set_rate_limit_invalid_category(self, test_client):
800800
assert response.status_code == 400
801801

802802
def test_set_rate_limit_invalid_count(self, test_client):
803-
"""PUT /admin/leaderboards/{name}/rate-limits rejects non-positive count."""
803+
"""PUT /admin/leaderboards/{name}/rate-limits rejects negative count."""
804804
response = test_client.put(
805805
"/admin/leaderboards/test-lb/rate-limits",
806806
headers={"Authorization": "Bearer test_token"},
807-
json={"mode_category": "test", "max_submissions_per_hour": 0},
807+
json={"mode_category": "test", "max_submissions_per_hour": -1},
808808
)
809809
assert response.status_code == 400
810810

tests/test_leaderboard_db.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,16 @@ def test_check_rate_limit_no_config(database, submit_leaderboard):
12221222
assert result is None
12231223

12241224

1225+
def test_check_rate_limit_zero_limit_blocks_submissions(database, submit_leaderboard):
1226+
"""A zero rate limit keeps a leaderboard visible while rejecting submissions."""
1227+
with database as db:
1228+
db.set_rate_limit("submit-leaderboard", "leaderboard", 0)
1229+
result = db.check_rate_limit("submit-leaderboard", "123", "leaderboard")
1230+
assert result["allowed"] is False
1231+
assert result["current_count"] == 0
1232+
assert result["max_per_hour"] == 0
1233+
1234+
12251235
def test_check_rate_limit_under_limit(database, submit_leaderboard):
12261236
"""check_rate_limit allows submissions under the limit."""
12271237
with database as db:

0 commit comments

Comments
 (0)