Added email verification

This commit is contained in:
ayxan 2022-09-10 01:35:48 +04:00
parent e513c2f6df
commit a7f615b336
10 changed files with 130 additions and 27 deletions

View File

@ -5,7 +5,7 @@ https://ayxan.pythonanywhere.com
**pip install -r requirements.txt<br />
cd src/<br />**
add SECRET_KEY to .env.example file<br />
add SECRET_KEY, EMAIL_HOST_PASSWORD to .env.example file<br />
rename .env.example to .env<br />
**python3 manage.py makemigrations account --settings=config.settings.development<br />

View File

@ -2,3 +2,4 @@ SECRET_KEY=
DB_NAME=
DB_USER=
DB_PASSWORD=
EMAIL_HOST_PASSWORD=

View File

@ -5,9 +5,21 @@ from .models import User
@admin.register(User)
class CustomAdmin(UserAdmin):
list_display = ('username', 'email')
fieldsets = UserAdmin.fieldsets + (
('IMDB API Key Field', {
'fields': ['imdb_api_key']
fieldsets = (
(None, {'fields': ('username', 'email', 'password')}),
(('Permissions'), {
'fields': ('is_active', 'email_notification_is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions'),
}),
(('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2'),
}),
)
list_display = ('username', 'email', 'is_staff')
list_filter = ('is_staff', 'email_notification_is_active', 'is_superuser', 'is_active', 'groups')
search_fields = ('email',)
ordering = ('email',)
filter_horizontal = ('groups', 'user_permissions',)

View File

@ -3,7 +3,11 @@ from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
first_name = None
last_name = None
email = models.EmailField('email', unique=True, blank=True, null=True)
imdb_api_key = models.CharField(max_length=15, blank=False, null=False)
email_notification_is_active = models.BooleanField(default=False)
class Meta:
db_table = 'user'

View File

@ -0,0 +1,6 @@
{% autoescape off %}
Hi {{ user.username }},
Please click on the link to confirm your registration,
http://{{ domain }}{% url 'activate' uidb64=uid token=token %}
If you think, it's not you, then just ignore this email.
{% endautoescape %}

View File

@ -8,8 +8,9 @@ urlpatterns = [
template_name = 'login.html'
), name='login'),
path('register', views.register_view, name='register'),
path('activate/<uidb64>/<token>/', views.activate_view, name='activate'),
path('logout', views.logout_view, name='logout'),
path('change-password', views.change_password_view, name='change-password'),
path('profile-editing', views.profile_editing_view, name='profile-editing'),
path('profile', views.ProfileDetailView.as_view(), name='profile')
path('profile', views.ProfileDetailView.as_view(), name='profile'),
]

View File

@ -1,4 +1,5 @@
from .register import register_view
from .register import (register_view,
activate_view)
from .logout import logout_view
from .change_password import change_password_view
from .profile_editing import profile_editing_view

View File

@ -1,8 +1,15 @@
from django.shortcuts import render, redirect
from django.shortcuts import (render,
redirect)
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from account.forms import ProfileEditingForm
from requests import get
from django.contrib.auth.tokens import default_token_generator
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.core.mail import EmailMessage
@login_required(login_url='/')
@ -10,6 +17,7 @@ def profile_editing_view(request):
if request.method == 'POST':
form = ProfileEditingForm(request.POST, instance=request.user)
if form.is_valid():
if 'imdb_api_key' in form.changed_data:
raw_data = get(f"https://imdb-api.com/en/API/Title/{request.POST['imdb_api_key']}/tt0110413")
if raw_data.status_code != 200:
@ -29,6 +37,26 @@ def profile_editing_view(request):
return redirect('profile-editing')
form.save()
if 'email' in form.changed_data:
user = request.user
user.email_notification_is_active = False
user.save()
to_email = form.cleaned_data.get('email')
current_site = get_current_site(request)
mail_subject = 'Activate your account.'
message = render_to_string('acc_active_email.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': default_token_generator.make_token(user),
})
email = EmailMessage(
mail_subject, message, to=[to_email]
)
email.send()
messages.warning(request, "Please confirm your email address to receive notifications of new episodes.")
return redirect('homepage')
messages.success(request, 'Profile Updated')
return redirect('homepage')

View File

@ -1,8 +1,18 @@
from django.shortcuts import render, redirect
from django.shortcuts import (render,
redirect)
from django.contrib import messages
from account.forms import RegisterForm
from django.contrib.auth import login, authenticate
from django.contrib.auth import (login,
authenticate)
from requests import get
from account.models import User
from django.contrib.auth.tokens import default_token_generator
from django.contrib.sites.shortcuts import get_current_site
from django.core.mail import EmailMessage
from django.shortcuts import render
from django.template.loader import render_to_string
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
def register_view(request):
@ -27,11 +37,27 @@ def register_view(request):
messages.info(request, f"IMDB API: {data['errorMessage']}")
return redirect('register')
to_email = form.cleaned_data.get('email')
form.save()
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password1')
user = authenticate(username=username, password=password)
login(request, user)
if to_email is not None:
current_site = get_current_site(request)
mail_subject = 'Activate your account.'
message = render_to_string('acc_active_email.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': default_token_generator.make_token(user),
})
email = EmailMessage(
mail_subject, message, to=[to_email]
)
email.send()
messages.warning(request, "Please confirm your email address to receive notifications of new episodes.")
return redirect('homepage')
messages.success(request, 'Registration Successful')
return redirect('homepage')
@ -40,3 +66,19 @@ def register_view(request):
form = RegisterForm()
return render(request, 'register.html', context={"form": form})
def activate_view(request, uidb64, token):
try:
uid = urlsafe_base64_decode(uidb64).decode()
user = User._default_manager.get(pk=uid)
except(TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user is not None and default_token_generator.check_token(user, token):
user.email_notification_is_active = True
user.save()
messages.success(request, "Thank you for your email confirmation. You will receive notifications of new episodes. ")
return redirect('homepage')
else:
messages.info(request, "Activation link is invalid!")
return redirect('register')

View File

@ -82,3 +82,11 @@ USE_I18N = True
USE_TZ = True
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
EMAIL_BACKEND = 'django_smtp_ssl.SSLEmailBackend'
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'series.notification@gmail.com'
EMAIL_HOST_PASSWORD = env("EMAIL_HOST_PASSWORD")
DEFAULT_FROM_EMAIL = 'series.notification@gmail.com'
EMAIL_PORT = 465