2022-08-08 09:43:31 +00:00
|
|
|
from django.contrib.auth.views import LoginView as DjangoLoginView
|
|
|
|
from django.contrib.auth import login
|
|
|
|
from django.utils.decorators import method_decorator
|
|
|
|
from django.views.decorators.debug import sensitive_post_parameters
|
|
|
|
from django.views.decorators.csrf import csrf_protect
|
|
|
|
from django.views.decorators.cache import never_cache
|
|
|
|
from django.core.exceptions import PermissionDenied
|
|
|
|
from django.http.response import HttpResponseRedirect
|
|
|
|
from django.urls import reverse
|
2022-09-18 16:45:35 +00:00
|
|
|
from django.contrib import messages
|
2022-08-08 09:43:31 +00:00
|
|
|
|
2022-09-16 15:40:15 +00:00
|
|
|
from ..models.auth import OTPSession, Profile
|
2022-08-08 09:43:31 +00:00
|
|
|
from ..forms.auth import OTPForm
|
|
|
|
|
|
|
|
|
|
|
|
class LoginView(DjangoLoginView):
|
|
|
|
template_name = "core/auth/login.html"
|
|
|
|
|
|
|
|
@method_decorator(sensitive_post_parameters())
|
|
|
|
@method_decorator(csrf_protect)
|
|
|
|
@method_decorator(never_cache)
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
|
|
if self.request.session.get("OTPSession"):
|
|
|
|
return HttpResponseRedirect(self.get_otp_url())
|
|
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
|
|
|
|
def get_otp_url(self):
|
|
|
|
return reverse("checkotp", kwargs={self.redirect_field_name: self.get_redirect_url()})
|
|
|
|
|
|
|
|
def form_valid(self, form):
|
|
|
|
if not (user := form.get_user()).totp:
|
|
|
|
login(self.request, user)
|
2022-09-16 15:40:15 +00:00
|
|
|
profile, _ = Profile.objects.get_or_create(user=user)
|
|
|
|
profile.save()
|
2022-08-08 09:43:31 +00:00
|
|
|
return HttpResponseRedirect(self.get_success_url())
|
|
|
|
|
|
|
|
session = OTPSession.objects.create(user=user)
|
|
|
|
self.request.session["OTPSession"] = session.uuid
|
|
|
|
|
|
|
|
return HttpResponseRedirect(self.get_otp_url())
|
|
|
|
|
2022-09-18 16:45:35 +00:00
|
|
|
def form_invalid(self, form):
|
|
|
|
messages.error(self.request, "The username or password you entered was incorrect. Please try again.")
|
|
|
|
return super().form_invalid(form)
|
|
|
|
|
2022-08-08 09:43:31 +00:00
|
|
|
|
|
|
|
class OTPView(DjangoLoginView):
|
|
|
|
authentication_form = OTPForm
|
|
|
|
|
|
|
|
@method_decorator(sensitive_post_parameters())
|
|
|
|
@method_decorator(csrf_protect)
|
|
|
|
@method_decorator(never_cache)
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
|
|
if not self.get_otpsession().is_alive():
|
|
|
|
del request.session["OTPSession"]
|
|
|
|
raise PermissionDenied("Your session has expired. Please try again.")
|
|
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
|
|
|
|
def get_otpsession(self):
|
|
|
|
return OTPSession.objects.get(uuid=self.request.session.get("OTPSession"))
|
|
|
|
|
|
|
|
def form_valid(self, form):
|
|
|
|
login(self.request, self.get_otpsession().user)
|
|
|
|
del request.session["OTPSession"]
|
2022-09-16 15:40:15 +00:00
|
|
|
profile, _ = Profile.objects.get_or_create(user=user)
|
|
|
|
profile.save()
|
2022-08-08 09:43:31 +00:00
|
|
|
return HttpResponseRedirect(self.get_success_url())
|
2022-09-18 16:45:35 +00:00
|
|
|
|
|
|
|
def form_invalid(self, form):
|
|
|
|
messages.error(self.request, "The One-Time Password you entered was incorrect. Please try again.")
|
|
|
|
return super().form_invalid(form)
|