feat: email confirmation
This commit is contained in:
parent
af1cdc2e10
commit
a841980274
@ -160,3 +160,4 @@ REST_FRAMEWORK = {
|
|||||||
|
|
||||||
URLS_PER_PAGE = 20
|
URLS_PER_PAGE = 20
|
||||||
READABILITY_HOST = os.getenv('READABILITY_HOST', None)
|
READABILITY_HOST = os.getenv('READABILITY_HOST', None)
|
||||||
|
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||||
|
5
later42/templates/email_activation.html
Normal file
5
later42/templates/email_activation.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{% autoescape off %}
|
||||||
|
Привет, {{ user.username }}.
|
||||||
|
Ссылка для активации аккаунта:
|
||||||
|
http://{{ domain }}{% url 'activate' uidb64=uid token=token %}
|
||||||
|
{% endautoescape %}
|
6
later42/templates/email_sent.html
Normal file
6
later42/templates/email_sent.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Активация аккаунта</h2>
|
||||||
|
<p>Письмо со ссылкой отправлено по указанному адресу.</p>
|
||||||
|
{% endblock %}
|
13
later42/tokens.py
Normal file
13
later42/tokens.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from django.contrib.auth.tokens import PasswordResetTokenGenerator
|
||||||
|
import six
|
||||||
|
|
||||||
|
|
||||||
|
class TokenGenerator(PasswordResetTokenGenerator):
|
||||||
|
def _make_hash_value(self, user, timestamp):
|
||||||
|
return (
|
||||||
|
six.text_type(user.pk) + six.text_type(timestamp) +
|
||||||
|
six.text_type(user.is_active)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
account_activation_token = TokenGenerator()
|
@ -22,7 +22,7 @@ from django.contrib.auth.views import LoginView
|
|||||||
from rest_framework import routers, serializers, viewsets
|
from rest_framework import routers, serializers, viewsets
|
||||||
|
|
||||||
from later42.forms import CustomLoginForm
|
from later42.forms import CustomLoginForm
|
||||||
from later42.views import index, profile, api, api_token, reader, signup, about
|
from later42.views import account_activation, index, profile, api, api_token, reader, signup, about
|
||||||
|
|
||||||
|
|
||||||
class UserSerializer(serializers.HyperlinkedModelSerializer):
|
class UserSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
@ -42,6 +42,8 @@ router.register(r'users', UserViewSet)
|
|||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('signup/', signup.register, name='signup'),
|
path('signup/', signup.register, name='signup'),
|
||||||
|
path(r'^activate/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
|
||||||
|
account_activation.activate, name='activate'),
|
||||||
path("accounts/login/",
|
path("accounts/login/",
|
||||||
LoginView.as_view(authentication_form=CustomLoginForm), name="login"),
|
LoginView.as_view(authentication_form=CustomLoginForm), name="login"),
|
||||||
path("accounts/", include("django.contrib.auth.urls")),
|
path("accounts/", include("django.contrib.auth.urls")),
|
||||||
|
29
later42/views/account_activation.py
Normal file
29
later42/views/account_activation.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import django
|
||||||
|
from django.core.mail import EmailMessage
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from later42.tokens import account_activation_token
|
||||||
|
from django.template.loader import render_to_string
|
||||||
|
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.shortcuts import render, redirect
|
||||||
|
from django.contrib.auth import login, authenticate
|
||||||
|
from later42.forms import SignUpForm
|
||||||
|
from django.contrib.sites.shortcuts import get_current_site
|
||||||
|
from django.utils.encoding import force_bytes
|
||||||
|
from django.utils.encoding import force_str
|
||||||
|
django.utils.encoding.force_text = force_str
|
||||||
|
|
||||||
|
|
||||||
|
def activate(request, uidb64, token):
|
||||||
|
try:
|
||||||
|
uid = django.utils.encoding.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 account_activation_token.check_token(user, token):
|
||||||
|
user.is_active = True
|
||||||
|
user.save()
|
||||||
|
login(request, user)
|
||||||
|
return redirect('index')
|
||||||
|
else:
|
||||||
|
return HttpResponse('Activation link is invalid!')
|
@ -1,21 +1,43 @@
|
|||||||
from django.contrib.auth import authenticate, login
|
from django.contrib.auth import authenticate, login
|
||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
|
from django.contrib.sites.shortcuts import get_current_site
|
||||||
|
from django.template.loader import render_to_string
|
||||||
|
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
|
||||||
|
from django.utils.encoding import force_bytes, force_text
|
||||||
|
from django.core.mail import EmailMessage
|
||||||
from later42.forms import SignUpForm
|
from later42.forms import SignUpForm
|
||||||
|
from later42.tokens import account_activation_token
|
||||||
|
|
||||||
|
|
||||||
def register(request):
|
def register(request):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = SignUpForm(request.POST)
|
form = SignUpForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
user = form.save()
|
user = form.save(commit=False)
|
||||||
user.refresh_from_db()
|
# user.refresh_from_db()
|
||||||
|
user.is_active = False
|
||||||
user.save()
|
user.save()
|
||||||
raw_password = form.cleaned_data.get('password1')
|
raw_password = form.cleaned_data.get('password1')
|
||||||
|
|
||||||
user = authenticate(username=user.username, password=raw_password)
|
current_site = get_current_site(request)
|
||||||
login(request, user)
|
|
||||||
|
|
||||||
return redirect('index')
|
# user = authenticate(username=user.username, password=raw_password)
|
||||||
|
# login(request, user)
|
||||||
|
|
||||||
|
mail_subject = 'Later42: Активация аккаунта'
|
||||||
|
message = render_to_string('email_activation.html', {
|
||||||
|
'user': user,
|
||||||
|
'domain': current_site.domain,
|
||||||
|
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
|
||||||
|
'token': account_activation_token.make_token(user),
|
||||||
|
})
|
||||||
|
to_email = form.cleaned_data.get('email')
|
||||||
|
email = EmailMessage(
|
||||||
|
mail_subject, message, to=[to_email]
|
||||||
|
)
|
||||||
|
email.send()
|
||||||
|
|
||||||
|
return render(request, 'email_sent.html')
|
||||||
else:
|
else:
|
||||||
form = SignUpForm()
|
form = SignUpForm()
|
||||||
return render(request, 'signup.html', {'form': form})
|
return render(request, 'signup.html', {'form': form})
|
||||||
|
@ -6,3 +6,4 @@ requests==2.28.1
|
|||||||
djangorestframework==3.14.0
|
djangorestframework==3.14.0
|
||||||
whitenoise==6.2.0
|
whitenoise==6.2.0
|
||||||
psycopg2-binary==2.9.4
|
psycopg2-binary==2.9.4
|
||||||
|
six==1.16.0
|
||||||
|
Loading…
Reference in New Issue
Block a user