Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions website/views/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
from django.contrib.sites.shortcuts import get_current_site
from django.core.cache import cache
from django.core.mail import send_mail
from django.db.models import Count, F, Q, Sum
from django.db.models.functions import ExtractMonth
Expand Down Expand Up @@ -187,6 +188,17 @@ def profile_edit(request):
defaults={"verified": False, "primary": False},
)

# Rate limit: atomic check-and-set to prevent race conditions
rate_key = f"email_verification_rate_{request.user.id}"

# add() only sets if key doesn't exist (atomic operation)
if not cache.add(rate_key, True, timeout=60):
messages.warning(
request,
"Too many requests. Please wait a minute before trying again.",
)
return redirect("profile", slug=request.user.username)

# Send verification email
try:
send_email_confirmation(request, request.user, email=new_email)
Expand Down
Loading