From 5f42ebdf74e2888d499c3e1c87e78c3fd0f89a8c Mon Sep 17 00:00:00 2001
From: Bobby
Date: Mon, 1 Aug 2022 19:20:26 +0530
Subject: feature: change user email address
---
blog/templates/account.html | 3 +-
.../templates/email_change_verification_email.html | 12 +++++
users/templates/verification_email.html | 2 +-
users/tokens.py | 12 +++++
users/urls.py | 2 +
users/views.py | 51 +++++++++++++++++++++-
6 files changed, 78 insertions(+), 4 deletions(-)
create mode 100644 users/templates/email_change_verification_email.html
diff --git a/blog/templates/account.html b/blog/templates/account.html
index 3c63eaa4..6e07cb6d 100644
--- a/blog/templates/account.html
+++ b/blog/templates/account.html
@@ -72,7 +72,8 @@
-
+Thanks for registering an account on {{ site_name }}. To verify and change your email address, please click the link below.
{{ protocol }}{{ domain }}{% url 'users:verifyemail' uidb64=uid token=token %}
Thanks,
diff --git a/users/tokens.py b/users/tokens.py
index 7bc5bc90..c127fa45 100644
--- a/users/tokens.py
+++ b/users/tokens.py
@@ -1,4 +1,7 @@
+import cryptocode
+import os
from django.contrib.auth.tokens import PasswordResetTokenGenerator
+from dotenv import load_dotenv
from six import text_type
class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
@@ -8,4 +11,13 @@ class AccountActivationTokenGenerator(PasswordResetTokenGenerator):
text_type(user.is_active)
)
+class EmailChangeTokenGenerator():
+ def encrypt(self, email):
+ auth_string = os.getenv('AUTHORIZATION_STRING')
+ return cryptocode.encrypt(email, auth_string)
+
+ def decrypt(self, token):
+ auth_string = os.getenv('AUTHORIZATION_STRING')
+ return cryptocode.decrypt(token, auth_string)
+
account_activation_token = AccountActivationTokenGenerator()
diff --git a/users/urls.py b/users/urls.py
index b7cd5f82..48b1d87b 100644
--- a/users/urls.py
+++ b/users/urls.py
@@ -11,6 +11,8 @@ urlpatterns = [
path('changepassword', views.change_password, name='changepassword'),
path('sendverificationemail', views.send_verification_email, name='sendverificationemail'),
path('verifyemail//', views.verify_email, name='verifyemail'),
+ path('sendchangeuseremail', views.send_change_user_email, name='sendchangeuseremail'),
+ path('changeemail//', views.change_email, name='changeemail'),
]
# Configure Admin Site
diff --git a/users/views.py b/users/views.py
index f4405a38..ce3b2c6f 100644
--- a/users/views.py
+++ b/users/views.py
@@ -11,7 +11,7 @@ from django.utils.html import strip_tags
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.contrib.sites.shortcuts import get_current_site
-from .tokens import account_activation_token
+from .tokens import account_activation_token, EmailChangeTokenGenerator
from django.utils.http import urlsafe_base64_decode
# Create your views here.
@@ -136,4 +136,51 @@ def verify_email(request, uidb64, token):
return redirect('/')
else:
messages.error(request, 'The verification link is invalid!')
- return redirect('/')
\ No newline at end of file
+ return redirect('/')
+
+def send_change_user_email(request):
+ user = request.user
+ new_email = request.POST['email']
+ if user is not None:
+ # check if email is already in use
+ if User.objects.filter(email=new_email).exists():
+ messages.error(request, 'Email is already in use!')
+ # Redirect to referrer
+ return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
+ # Check if the new and the old email are the same
+ if user.email == new_email:
+ messages.error(request, 'New email is the same as the old one!')
+ return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
+ # Send verification email
+ subject = 'Verify your email address'
+ message = render_to_string('email_change_verification_email.html', {
+ 'user': user.username if user.first_name is None else user.first_name,
+ 'site_name': 'That Computer Scientist',
+ 'uid': urlsafe_base64_encode(force_bytes(user.pk)),
+ 'token': EmailChangeTokenGenerator().encrypt(new_email),
+ 'protocol': 'https://' if request.is_secure() else 'http://',
+ 'domain': get_current_site(request).domain,
+ })
+ message = strip_tags(message)
+ send_mail(subject, message, 'That Computer Scientist <' + settings.EMAIL_HOST_USER + '>', [new_email])
+ messages.success(request, 'Verification email was sent! Please check your email.')
+ return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
+ else:
+ messages.error(request, 'Unable to change email! Please try again later.')
+ return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
+
+def change_email(request, uidb64, token):
+ try:
+ uid = urlsafe_base64_decode(uidb64).decode()
+ user = User.objects.get(pk=uid)
+ new_email = EmailChangeTokenGenerator().decrypt(token)
+ except (TypeError, ValueError, OverflowError, User.DoesNotExist):
+ user = None
+ if user is not None:
+ user.email = new_email
+ user.save()
+ messages.success(request, 'Email was successfully changed!')
+ return redirect('/account')
+ else:
+ messages.error(request, 'The verification link is invalid!')
+ return redirect('/')
--
cgit v1.2.3