from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth import login as login_user from django.contrib.auth import logout as logout_user from django.contrib.auth.tokens import default_token_generator from django.core.exceptions import ValidationError from django.db import IntegrityError from django.shortcuts import redirect, render, reverse from django.utils.http import url_has_allowed_host_and_scheme, urlsafe_base64_decode from django.utils.text import gettext_lazy as _ from django.views.generic import TemplateView, View from shop.models import CustomerAddress from users.forms import LoginForm, PasswordResetForm, RegisterForm, SetPasswordForm from web.models import WebSettings User = get_user_model() class RedirectionMixin: redirect_to = "" def get_redirection(self): return reverse(self.redirect_to) class LoginView(View, RedirectionMixin): template_name = "users/login.html" redirect_to = "web:index" login_form_class = LoginForm def get_login_form(self, request): return self.login_form_class(data=request.POST) def get(self, request, *args, **kwargs): if request.user.is_authenticated: return redirect(self.get_redirection()) settings = WebSettings.load() login_form = self.login_form_class() return render( request, self.template_name, { "form": login_form, "title": settings.web_title, "description": _("inicio de sesión"), }, ) def post(self, request, *args, **kwargs): login_form = self.get_login_form(request) if login_form.is_valid(): login_user(request, login_form.get_user()) if not login_form.cleaned_data.get("remember_me"): request.session.set_expiry(0) return redirect(self.get_redirection()) return render(request, self.template_name, { "form": login_form, "errors": login_form.errors.get('__all__'), }, status=400) class RegisterView(TemplateView, RedirectionMixin): template_name = "users/register.html" redirect_to = "web:login" form_class = RegisterForm def get_context_data(self, **kwargs): settings = WebSettings.load() return { "form": self.form_class(), "title": settings.web_title, "description": _("crear cuenta"), } def post(self, request, *args, **kwargs): settings = WebSettings.load() form = self.form_class(request.POST) errors = [] try: if form.is_valid(): user = form.save() user.username = user.email user.first_name = form.cleaned_data.get("first_name") user.last_name = form.cleaned_data.get("last_name") user.save() login(request, user) return redirect(self.get_redirection()) else: errors = form.errors except IntegrityError as e: errors = [ _("Ya existe un usuario con ese correo electrónico"), ] return render( request, self.template_name, { "form": form, "title": settings.web_title, "description": _("Crear cuenta"), "errors": errors, }, status=400, ) class LogoutView(View, RedirectionMixin): redirect_to = "web:index" def get(self, request, *args, **kwargs): logout_user(request) return redirect(self.get_redirection()) def post(self, request, *args, **kwargs): logout_user(request) return redirect(self.get_redirection()) class ResetPasswordView(TemplateView): template_name = "users/reset_password.html" form_class = PasswordResetForm redirect_to = "web:reset_password_email_sent" html_reset_password_template_name = "mails/reset_password.html" subject_template_name = "mails/subject_reset_password.txt" def get_email_options(self): return { "extra_email_context": {}, "email_template_name": self.html_reset_password_template_name, "html_email_template_name": self.html_reset_password_template_name, "subject_template_name": self.subject_template_name, } def get_base_context(self): settings = WebSettings.load() return { "title": settings.web_title, "description": _("Restablecer contraseña"), } def get_context_data(self, **kwargs): context = self.get_base_context() context.update({"form": self.form_class()}) return context def post(self, request, *args, **kwargs): form = self.form_class(request.POST) if form.is_valid(): opts = { "use_https": request.is_secure(), "from_email": getattr(settings, "DEFAULT_FROM_EMAIL"), "request": request, } opts.update(self.get_email_options()) form.save(**opts) return redirect(self.redirect_to) context = self.get_base_context() context.update({"form": form}) return render(request, self.template_name, context) class ResetPasswordEmailSent(TemplateView): template_name = "users/reset_password_email_sent.html" def get_context_data(self, **kwargs): settings = WebSettings.load() return { "title": settings.web_title, "description": settings.web_description, } class ResetPasswordConfirmView(TemplateView): template_name = "users/reset_password_confirm.html" form_class = SetPasswordForm redirect_to = "web:login" token_generator = default_token_generator def get_user(self): try: uidb64 = self.kwargs.get("uidb64") uid = urlsafe_base64_decode(uidb64).decode() user = User.objects.get(pk=uid) except ( TypeError, ValueError, OverflowError, User.DoesNotExist, ValidationError, ): user = None return user def generate_new_token_for_user(self, user): return self.token_generator.make_token(user) def get_context_data(self, **kwargs): user = self.get_user() valid_token = self.check_token(user) new_token = self.generate_new_token_for_user(user) return { "title": WebSettings.load().web_title, "description": _("Establecer nueva contraseña"), "form": self.form_class(user, {"token": new_token}), "valid_token": valid_token, "new_token": new_token, } def check_token(self, user): token = self.kwargs.get("token") valid_token = self.token_generator.check_token(user, token) return valid_token def post(self, request, *args, **kwargs): user = self.get_user() form = self.form_class(user, request.POST) if form.is_valid(): form.save() return redirect(self.redirect_to) return render(request, self.template_name, {}) class MyAccountView(TemplateView): template_name = "users/user_details.html" def get_context_data(self, **kwargs): addresses = CustomerAddress.objects.filter(user=self.request.user) settings = WebSettings.load() return { "customer_addresses": addresses, } login = LoginView.as_view() logout = LogoutView.as_view() register = RegisterView.as_view() reset_password = ResetPasswordView.as_view() reset_password_confirm = ResetPasswordConfirmView.as_view() reset_password_email_sent = ResetPasswordEmailSent.as_view() my_account = MyAccountView.as_view()