fix(crm): rate limit appointment slot lookups on the booking page

(cherry picked from commit acf0863513)

# Conflicts:
#	erpnext/www/book_appointment/index.py
This commit is contained in:
Nabin Hait
2026-10-22 09:32:36 +00:00
committed by Mergify
parent e007159c21
commit 246bdd5374
2 changed files with 21 additions and 0 deletions
@@ -292,6 +292,19 @@ class TestAppointment(FrappeTestCase):
},
)
def test_portal_slot_requests_are_rate_limited(self):
from erpnext.www.book_appointment.index import SLOT_REQUESTS_PER_MINUTE
self.addCleanup(setattr, frappe.local, "request", getattr(frappe.local, "request", None))
self.addCleanup(frappe.cache.delete_keys, "rl:")
set_request(method="GET", path="/api/method/erpnext.www.book_appointment.index.get_appointment_slots")
frappe.local.request_ip = "127.0.0.9"
with self.set_user("Guest"):
for _ in range(SLOT_REQUESTS_PER_MINUTE):
self.assertRaises(TypeError, get_appointment_slots)
self.assertRaises(frappe.RateLimitExceededError, get_appointment_slots)
def test_booked_slot_unavailable_on_portal(self):
self._configure_booking_settings()
tz = get_system_timezone()
+8
View File
@@ -7,6 +7,7 @@ from frappe import _
from frappe.rate_limiter import rate_limit
from frappe.utils.data import get_system_timezone
SLOT_REQUESTS_PER_MINUTE = 60
WEEKDAYS = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
no_cache = 1
@@ -48,8 +49,15 @@ def get_timezones():
return pytz.all_timezones
<<<<<<< HEAD
@frappe.whitelist(allow_guest=True)
def get_appointment_slots(date, timezone):
=======
# nosemgrep: frappe-semgrep-rules.rules.security.guest-whitelisted-method -- reviewed: public booking page; rate limited, returns free slots only, booking must be enabled
@frappe.whitelist(allow_guest=True)
@rate_limit(limit=SLOT_REQUESTS_PER_MINUTE, seconds=60)
def get_appointment_slots(date: str, timezone: str):
>>>>>>> acf0863 (fix(crm): rate limit appointment slot lookups on the booking page)
# Convert query to local timezones
handle_appointment_booking_disabled()
format_string = "%Y-%m-%d %H:%M:%S"