Skip to content

Commit 8babc8e

Browse files
committed
Implement basic rate limiting of submissions
For now, the rate limit is no more than 3 submissions in the past 10 minutes. Details can be tweaked.
1 parent bb7cac0 commit 8babc8e

File tree

1 file changed

+29
-22
lines changed

1 file changed

+29
-22
lines changed

pgweb/util/helpers.py

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from pgweb.util.contexts import render_pgweb
99
from pgweb.util.moderation import ModerationState
1010

11+
from datetime import datetime, timedelta
1112
import io
1213
import difflib
1314

@@ -64,29 +65,35 @@ def simple_form(instancetype, itemid, request, formclass, formtemplate='base/for
6465
if not is_new:
6566
old_values = {fn: str(getattr(instance, fn)) for fn in form.changed_data if hasattr(instance, fn)}
6667

67-
if form.is_valid():
68-
# We are handling notifications, so disable the ones we'd otherwise send
69-
do_notify = getattr(instance, 'send_notification', False)
70-
instance.send_notification = False
71-
72-
# If the object has an "approved" field and it's set to false, we don't
73-
# bother notifying about the changes. But if it lacks this field, we notify
74-
# about everything, as well as if the field exists and the item has already
75-
# been approved.
76-
# Newly added objects are always notified if they are two-state, but not if they
77-
# are tri-state (in which case they get notified when submitted for
78-
# moderation).
79-
if is_new:
80-
if hasattr(instance, 'modstate'):
81-
# Tri-state indicated by the existence of the modstate field
68+
# We are handling notifications, so disable the ones we'd otherwise send
69+
do_notify = getattr(instance, 'send_notification', False)
70+
instance.send_notification = False
71+
72+
# If the object has an "approved" field and it's set to false, we don't
73+
# bother notifying about the changes. But if it lacks this field, we notify
74+
# about everything, as well as if the field exists and the item has already
75+
# been approved.
76+
# Newly added objects are always notified if they are two-state, but not if they
77+
# are tri-state (in which case they get notified when submitted for
78+
# moderation).
79+
if is_new:
80+
if hasattr(instance, 'modstate'):
81+
# Tri-state indicated by the existence of the modstate field
82+
do_notify = False
83+
else:
84+
if hasattr(instance, 'approved'):
85+
if not getattr(instance, 'approved', True):
8286
do_notify = False
83-
else:
84-
if hasattr(instance, 'approved'):
85-
if not getattr(instance, 'approved', True):
86-
do_notify = False
87-
elif hasattr(instance, 'modstate'):
88-
if getattr(instance, 'modstate', None) == ModerationState.CREATED:
89-
do_notify = False
87+
elif hasattr(instance, 'modstate'):
88+
if getattr(instance, 'modstate', None) == ModerationState.CREATED:
89+
do_notify = False
90+
91+
# Do some very trivial rate limiting. The idea is "no more than <n> submission events in <t> time",
92+
# the numbers of <n> and <t> being entirely arbitrary.
93+
if do_notify and form.is_valid() and UserSubmission.objects.filter(user=request.user, when__gte=datetime.now() - timedelta(minutes=10)).count() > 2:
94+
form.add_error(None, 'You have made too many submissions in a short time. Please wait a little and try again.')
95+
96+
if form.is_valid():
9097

9198
notify = io.StringIO()
9299

0 commit comments

Comments
 (0)