from corres2math.tokens import email_validation_token from django.conf import settings from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.models import User from django.core.exceptions import ValidationError from django.db import transaction from django.shortcuts import redirect, resolve_url from django.urls import reverse_lazy from django.utils.http import urlsafe_base64_decode from django.utils.translation import gettext_lazy as _ from django.views.generic import CreateView, DetailView, RedirectView, TemplateView, UpdateView from .forms import CoachRegistrationForm, SignupForm, StudentRegistrationForm, UserForm class SignupView(CreateView): model = User form_class = SignupForm template_name = "registration/signup.html" def get_context_data(self, **kwargs): context = super().get_context_data() context["student_registration_form"] = StudentRegistrationForm(self.request.POST or None) context["coach_registration_form"] = CoachRegistrationForm(self.request.POST or None) return context @transaction.atomic def form_valid(self, form): role = form.cleaned_data["role"] if role == "participant": registration_form = StudentRegistrationForm(self.request.POST) else: registration_form = CoachRegistrationForm(self.request.POST) if not registration_form.is_valid(): return self.form_invalid(form) ret = super().form_valid(form) registration = registration_form.instance registration.user = form.instance registration.save() return ret def get_success_url(self): return reverse_lazy("registration:email_validation_sent") class UserValidateView(TemplateView): """ A view to validate the email address. """ title = _("Email validation") template_name = 'registration/email_validation_complete.html' extra_context = {"title": _("Validate email")} def get(self, *args, **kwargs): """ With a given token and user id (in params), validate the email address. """ assert 'uidb64' in kwargs and 'token' in kwargs self.validlink = False user = self.get_user(kwargs['uidb64']) token = kwargs['token'] # Validate the token if user is not None and email_validation_token.check_token(user, token): self.validlink = True user.registration.email_confirmed = True user.registration.save() return self.render_to_response(self.get_context_data(), status=200 if self.validlink else 400) def get_user(self, uidb64): """ Get user from the base64-encoded string. """ try: # urlsafe_base64_decode() decodes to bytestring uid = urlsafe_base64_decode(uidb64).decode() user = User.objects.get(pk=uid) except (TypeError, ValueError, OverflowError, User.DoesNotExist, ValidationError): user = None return user def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['user_object'] = self.get_user(self.kwargs["uidb64"]) context['login_url'] = resolve_url(settings.LOGIN_URL) if self.validlink: context['validlink'] = True else: context.update({ 'title': _('Email validation unsuccessful'), 'validlink': False, }) return context class UserValidationEmailSentView(TemplateView): """ Display the information that the validation link has been sent. """ template_name = 'registration/email_validation_email_sent.html' extra_context = {"title": _('Email validation email sent')} class UserResendValidationEmailView(LoginRequiredMixin, DetailView): """ Rensend the email validation link. """ model = User extra_context = {"title": _("Resend email validation link")} def get(self, request, *args, **kwargs): user = self.get_object() user.registration.send_email_validation_link() return redirect('registration:email_validation_sent') class MyAccountDetailView(LoginRequiredMixin, RedirectView): def get_redirect_url(self, *args, **kwargs): return reverse_lazy("registration:user_detail", args=(self.request.user.pk,)) class UserDetailView(LoginRequiredMixin, DetailView): model = User template_name = "registration/user_detail.html" class UserUpdateView(LoginRequiredMixin, UpdateView): model = User form_class = UserForm template_name = "registration/update_user.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) user = self.get_object() context["registration_form"] = user.registration.form_class(data=self.request.POST or None, instance=self.object.registration) return context @transaction.atomic def form_valid(self, form): user = form.instance registration_form = user.registration.form_class(data=self.request.POST or None, instance=self.object.registration) if not registration_form.is_valid(): return self.form_invalid(form) registration_form.save() return super().form_valid(form) def get_success_url(self): return reverse_lazy("registration:user_detail", args=(self.object.pk,))