NDOJ/judge/views/email.py
2023-08-25 15:58:59 -05:00

110 lines
3.6 KiB
Python

from django.contrib.auth.tokens import default_token_generator
from django.core.mail import send_mail
from django.shortcuts import render, redirect
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes, force_text
from django.conf import settings
from django import forms
from django.utils.translation import gettext_lazy as _
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from urllib.parse import urlencode, urlunparse, urlparse
from judge.models import Profile
from judge.utils.email_render import render_email_message
class EmailChangeForm(forms.Form):
new_email = forms.EmailField(label=_("New Email"))
def clean_new_email(self):
new_email = self.cleaned_data.get("new_email")
if User.objects.filter(email=new_email).exists():
raise forms.ValidationError(_("An account with this email already exists."))
return new_email
@login_required
def email_change_view(request):
form = EmailChangeForm(request.POST or None)
if request.method == "POST" and form.is_valid():
new_email = request.POST.get("new_email")
user = request.user
profile = request.profile
# Generate a token for email verification
token = default_token_generator.make_token(user)
uid = urlsafe_base64_encode(force_bytes(user.pk))
# Send the email to the user
subject = settings.SITE_NAME + " - " + _("Email Change Request")
email_contexts = {
"message": _(
"We have received a request to change your email to this email. Click the button below to change your email:"
),
"title": _("Email Change"),
"button_text": _("Change Email"),
"url_path": reverse(
"email_change_verify", kwargs={"uidb64": uid, "token": token}
),
}
message = render_email_message(request, email_contexts)
send_mail(
subject,
message,
settings.EMAIL_HOST_USER,
[new_email],
html_message=message,
)
profile.email_change_pending = new_email
profile.save()
return redirect("email_change_pending")
return render(
request,
"email_change/email_change.html",
{
"form": form,
"title": _("Change email"),
},
)
def verify_email_view(request, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user is not None and default_token_generator.check_token(user, token):
# Update the user's email address
profile = Profile.objects.get(user=user)
new_email = profile.email_change_pending
if new_email:
user.email = new_email
profile.email_change_pending = None
user.save()
profile.save()
return render(
request,
"email_change/email_change_success.html",
{"title": _("Success"), "user": user},
)
return render(
request, "email_change/email_change_failure.html", {"title": _("Invalid")}
)
def email_change_pending_view(request):
return render(
request,
"email_change/email_change_pending.html",
{
"title": _("Email change pending"),
},
)