201 lines
9.8 KiB
Python
201 lines
9.8 KiB
Python
from django.shortcuts import render, redirect, get_object_or_404
|
||
from django.contrib.auth import login, authenticate, logout
|
||
from django.contrib import messages
|
||
from django.core.mail import send_mail
|
||
from django.conf import settings
|
||
from django.urls import reverse
|
||
from django.shortcuts import redirect
|
||
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
|
||
from django.utils.encoding import force_bytes, force_str
|
||
from django.contrib.auth.tokens import default_token_generator
|
||
from django.contrib.auth.decorators import login_required
|
||
from django.contrib.auth import update_session_auth_hash
|
||
from django.contrib.auth.forms import PasswordChangeForm
|
||
from .forms import CustomUserCreationForm, PasswordResetForm
|
||
from .models import CustomUser
|
||
import uuid
|
||
|
||
|
||
def register(request):
|
||
if request.method == 'POST':
|
||
form = CustomUserCreationForm(request.POST)
|
||
if form.is_valid():
|
||
user = form.save(commit=False)
|
||
user.is_active = False # Пользователь не активен до подтверждения email
|
||
user.save()
|
||
|
||
# Отправляем письмо с подтверждением
|
||
confirmation_url = request.build_absolute_uri(
|
||
reverse('accounts:confirm_email', kwargs={'token': user.email_confirmation_token})
|
||
)
|
||
|
||
subject = 'Подтверждение Email'
|
||
message = f'Привет {user.name}!\n\nДля подтверждения вашего email перейдите по следующей ссылке: {confirmation_url}\n\nСпасибо за регистрацию!'
|
||
from_email = settings.DEFAULT_FROM_EMAIL
|
||
recipient_list = [user.email]
|
||
|
||
# Выводим письмо в консоль, как вы просили
|
||
print(f"Письмо для подтверждения:\nТема: {subject}\nСообщение:\n{message}\nПолучатель: {recipient_list}")
|
||
|
||
# В реальной системе отправили бы письмо:
|
||
# send_mail(subject, message, from_email, recipient_list, fail_silently=False)
|
||
|
||
messages.success(request, 'Пожалуйста, проверьте вашу почту для подтверждения email.')
|
||
return redirect('accounts:login')
|
||
else:
|
||
form = CustomUserCreationForm()
|
||
|
||
return render(request, 'register.html', {'form': form})
|
||
|
||
|
||
def register_view(request):
|
||
if request.method == 'POST':
|
||
form = CustomUserCreationForm(request.POST)
|
||
if form.is_valid():
|
||
user = form.save(commit=False)
|
||
user.is_active = False # Пользователь не активен до подтверждения email
|
||
user.save()
|
||
|
||
# Отправляем письмо с подтверждением (выводим в консоль)
|
||
confirmation_url = request.build_absolute_uri(
|
||
f'/accounts/confirm/{user.email_confirmation_token}/'
|
||
)
|
||
|
||
subject = 'Подтверждение Email'
|
||
message = f'Привет {user.name}!\n\nДля подтверждения вашего email перейдите по следующей ссылке: {confirmation_url}\n\nСпасибо за регистрацию!'
|
||
from_email = 'noreply@example.com' # Используем значение из настроек
|
||
recipient_list = [user.email]
|
||
|
||
# Выводим письмо в консоль, как вы просили
|
||
print(f"Письмо для подтверждения:\nТема: {subject}\nСообщение:\n{message}\nПолучатель: {recipient_list}")
|
||
|
||
messages.success(request, 'Пожалуйста, проверьте вашу почту для подтверждения email.')
|
||
return redirect('accounts:login') # Перенаправляем на страницу входа после регистрации
|
||
else:
|
||
form = CustomUserCreationForm()
|
||
|
||
return render(request, 'register.html', {'form': form})
|
||
|
||
|
||
def login_view(request):
|
||
if request.method == 'POST':
|
||
email = request.POST.get('email')
|
||
password = request.POST.get('password')
|
||
|
||
# Используем email как логин
|
||
user = authenticate(request, username=email, password=password)
|
||
|
||
if user is not None:
|
||
if user.is_email_confirmed: # Проверяем, подтвержден ли email
|
||
login(request, user)
|
||
# Перенаправляем на главную страницу после успешного входа
|
||
next_page = request.GET.get('next', 'index') # Если есть параметр next, переходим туда
|
||
return redirect(next_page)
|
||
else:
|
||
messages.error(request, 'Пожалуйста, подтвердите ваш email для входа.')
|
||
else:
|
||
messages.error(request, 'Неверный email или пароль.')
|
||
|
||
return render(request, 'login.html')
|
||
|
||
|
||
def logout_view(request):
|
||
logout(request)
|
||
return redirect('index')
|
||
|
||
|
||
@login_required
|
||
def profile_view(request):
|
||
return render(request, 'profile.html', {'user': request.user})
|
||
|
||
|
||
@login_required
|
||
def change_password_view(request):
|
||
if request.method == 'POST':
|
||
form = PasswordChangeForm(request.user, request.POST)
|
||
if form.is_valid():
|
||
user = form.save()
|
||
update_session_auth_hash(request, user) # Important for keeping the user logged in
|
||
messages.success(request, 'Ваш пароль был успешно изменен!')
|
||
return redirect('profile')
|
||
else:
|
||
messages.error(request, 'Пожалуйста, исправьте ошибки в форме.')
|
||
else:
|
||
form = PasswordChangeForm(request.user)
|
||
|
||
return render(request, 'change_password.html', {'form': form})
|
||
|
||
|
||
def confirm_email(request, token):
|
||
user = get_object_or_404(CustomUser, email_confirmation_token=token)
|
||
|
||
if user.is_email_confirmed:
|
||
messages.info(request, 'Email уже был подтвержден.')
|
||
else:
|
||
user.confirm_email()
|
||
user.is_active = True # Активируем пользователя
|
||
user.save()
|
||
messages.success(request, 'Email успешно подтвержден! Теперь вы можете войти.')
|
||
|
||
return redirect('accounts:login')
|
||
|
||
|
||
def password_reset_request(request):
|
||
if request.method == 'POST':
|
||
form = PasswordResetForm(request.POST)
|
||
if form.is_valid():
|
||
email = form.cleaned_data['email']
|
||
try:
|
||
user = CustomUser.objects.get(email=email)
|
||
|
||
# Генерируем токен восстановления
|
||
user.password_reset_token = uuid.uuid4()
|
||
user.save()
|
||
|
||
# Отправляем письмо с инструкциями по восстановлению
|
||
reset_url = request.build_absolute_uri(
|
||
reverse('accounts:password_reset_confirm', kwargs={'token': user.password_reset_token})
|
||
)
|
||
|
||
subject = 'Восстановление пароля'
|
||
message = f'Привет {user.name}!\n\nДля восстановления пароля перейдите по следующей ссылке: {reset_url}\n\nЕсли вы не запрашивали восстановление пароля, проигнорируйте это письмо.'
|
||
from_email = settings.DEFAULT_FROM_EMAIL
|
||
recipient_list = [user.email]
|
||
|
||
# Выводим письмо в консоль
|
||
print(f"Письмо для восстановления пароля:\nТема: {subject}\nСообщение:\n{message}\nПолучатель: {recipient_list}")
|
||
|
||
messages.success(request, f'Инструкции по восстановлению пароля отправлены на {email}')
|
||
except CustomUser.DoesNotExist:
|
||
# Для безопасности не сообщаем, что пользователя не существует
|
||
messages.success(request, 'Если аккаунт с таким email существует, инструкции по восстановлению пароля были отправлены на него.')
|
||
|
||
return redirect('accounts:login')
|
||
else:
|
||
form = PasswordResetForm()
|
||
|
||
return render(request, 'login.html', {'form': form})
|
||
|
||
|
||
def password_reset_confirm(request, token):
|
||
try:
|
||
user = CustomUser.objects.get(password_reset_token=token)
|
||
except CustomUser.DoesNotExist:
|
||
messages.error(request, 'Ссылка для восстановления пароля недействительна.')
|
||
return redirect('index')
|
||
|
||
if request.method == 'POST':
|
||
password1 = request.POST.get('password1')
|
||
password2 = request.POST.get('password2')
|
||
|
||
if password1 and password2 and password1 == password2:
|
||
user.set_password(password1)
|
||
user.password_reset_token = None # Обнуляем токен
|
||
user.save()
|
||
messages.success(request, 'Пароль успешно изменен. Теперь вы можете войти.')
|
||
return redirect('accounts:login')
|
||
else:
|
||
messages.error(request, 'Пароли не совпадают.')
|
||
|
||
# Отображаем форму смены пароля
|
||
return render(request, 'accounts/password_reset_confirm.html', {'user': user}) |