diff --git a/later42/settings.py b/later42/settings.py
index aa31f05..1dd70af 100644
--- a/later42/settings.py
+++ b/later42/settings.py
@@ -160,3 +160,4 @@ REST_FRAMEWORK = {
URLS_PER_PAGE = 20
READABILITY_HOST = os.getenv('READABILITY_HOST', None)
+EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
diff --git a/later42/templates/email_activation.html b/later42/templates/email_activation.html
new file mode 100644
index 0000000..179e6d0
--- /dev/null
+++ b/later42/templates/email_activation.html
@@ -0,0 +1,5 @@
+{% autoescape off %}
+Привет, {{ user.username }}.
+Ссылка для активации аккаунта:
+http://{{ domain }}{% url 'activate' uidb64=uid token=token %}
+{% endautoescape %}
\ No newline at end of file
diff --git a/later42/templates/email_sent.html b/later42/templates/email_sent.html
new file mode 100644
index 0000000..884af1b
--- /dev/null
+++ b/later42/templates/email_sent.html
@@ -0,0 +1,6 @@
+{% extends 'base.html' %}
+
+{% block content %}
+
Активация аккаунта
+Письмо со ссылкой отправлено по указанному адресу.
+{% endblock %}
diff --git a/later42/tokens.py b/later42/tokens.py
new file mode 100644
index 0000000..a2fa72e
--- /dev/null
+++ b/later42/tokens.py
@@ -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()
diff --git a/later42/urls.py b/later42/urls.py
index eb9de87..39d2929 100644
--- a/later42/urls.py
+++ b/later42/urls.py
@@ -22,7 +22,7 @@ from django.contrib.auth.views import LoginView
from rest_framework import routers, serializers, viewsets
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):
@@ -42,6 +42,8 @@ router.register(r'users', UserViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('signup/', signup.register, name='signup'),
+ path(r'^activate/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
+ account_activation.activate, name='activate'),
path("accounts/login/",
LoginView.as_view(authentication_form=CustomLoginForm), name="login"),
path("accounts/", include("django.contrib.auth.urls")),
diff --git a/later42/views/account_activation.py b/later42/views/account_activation.py
new file mode 100644
index 0000000..4eb7ccf
--- /dev/null
+++ b/later42/views/account_activation.py
@@ -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!')
diff --git a/later42/views/signup.py b/later42/views/signup.py
index 4ac27d7..a6a5bf5 100644
--- a/later42/views/signup.py
+++ b/later42/views/signup.py
@@ -1,21 +1,43 @@
from django.contrib.auth import authenticate, login
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.tokens import account_activation_token
def register(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
- user = form.save()
- user.refresh_from_db()
+ user = form.save(commit=False)
+ # user.refresh_from_db()
+ user.is_active = False
user.save()
raw_password = form.cleaned_data.get('password1')
- user = authenticate(username=user.username, password=raw_password)
- login(request, user)
+ current_site = get_current_site(request)
- 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:
form = SignUpForm()
return render(request, 'signup.html', {'form': form})
diff --git a/requirements.txt b/requirements.txt
index a392712..be382a6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -6,3 +6,4 @@ requests==2.28.1
djangorestframework==3.14.0
whitenoise==6.2.0
psycopg2-binary==2.9.4
+six==1.16.0