110 lines
4.5 KiB
Python
110 lines
4.5 KiB
Python
|
from django.contrib.auth import REDIRECT_FIELD_NAME, logout
|
||
|
from django.contrib.auth.views import SuccessURLAllowedHostsMixin
|
||
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||
|
from django.contrib import messages
|
||
|
from django.conf import settings
|
||
|
from django.utils import timezone
|
||
|
from django.utils.http import url_has_allowed_host_and_scheme
|
||
|
from django.http import HttpResponseRedirect
|
||
|
from django.shortcuts import resolve_url
|
||
|
|
||
|
from ..models.session import AuthSession
|
||
|
|
||
|
|
||
|
class AuthSessionRequiredMixin(SuccessURLAllowedHostsMixin):
|
||
|
redirect_field_name = REDIRECT_FIELD_NAME
|
||
|
redirect_authenticated_user = True
|
||
|
|
||
|
def dispatch(self, request, *args, **kwargs):
|
||
|
if not request.session["AuthSession"]:
|
||
|
if request.user.is_authenticated and self.redirect_authenticated_user:
|
||
|
redirect_to = self.request.POST.get(
|
||
|
self.redirect_field_name,
|
||
|
self.request.GET.get(self.redirect_field_name, '')
|
||
|
)
|
||
|
url_is_safe = url_has_allowed_host_and_scheme(
|
||
|
url=redirect_to,
|
||
|
allowed_hosts=self.get_success_url_allowed_hosts(),
|
||
|
require_https=self.request.is_secure(),
|
||
|
)
|
||
|
url = redirect_to if url_is_safe else resolve_url(
|
||
|
settings.LOGIN_REDIRECT_URL)
|
||
|
|
||
|
if url == self.request.path:
|
||
|
raise ValueError(
|
||
|
"Redirection loop for authenticated user detected. Check that "
|
||
|
"your LOGIN_REDIRECT_URL doesn't point to a login page."
|
||
|
)
|
||
|
return HttpResponseRedirect(url)
|
||
|
|
||
|
if not request.user.is_authenticated:
|
||
|
messages.error(
|
||
|
request, "Could not identify your login session, please try again.")
|
||
|
url = resolve_url(settings.LOGIN_URL)
|
||
|
if params := request.GET.urlencode():
|
||
|
url += f"?{params}"
|
||
|
return HttpResponseRedirect(url)
|
||
|
|
||
|
if request.user.is_authenticated:
|
||
|
logout(request)
|
||
|
messages.error(
|
||
|
request, "This shouldn't happen. Looks like you are logged in *and* logging in. Logged you out, just to be sure. Please try logging in again. Sorry!")
|
||
|
request.session["AuthSession"] = None
|
||
|
url = resolve_url(settings.LOGIN_URL)
|
||
|
if params := request.GET.urlencode():
|
||
|
url += f"?{params}"
|
||
|
return HttpResponseRedirect(url)
|
||
|
|
||
|
try:
|
||
|
session = AuthSession.objects.get(
|
||
|
id=request.session["AuthSession"])
|
||
|
if session.expiry < timezone.now():
|
||
|
request.session["AuthSession"] = None
|
||
|
messages.error(
|
||
|
request, "Your session has expired. Please try logging in again.")
|
||
|
url = resolve_url(settings.LOGIN_URL)
|
||
|
if params := request.GET.urlencode():
|
||
|
url += f"?{params}"
|
||
|
return HttpResponseRedirect(url)
|
||
|
|
||
|
except AuthSession.DoesNotExist:
|
||
|
request.session["AuthSession"] = None
|
||
|
messages.error(
|
||
|
request, "You are trying to access a session that doesn't exist...? Please try logging in again.")
|
||
|
url = resolve_url(settings.LOGIN_URL)
|
||
|
if params := request.GET.urlencode():
|
||
|
url += f"?{params}"
|
||
|
return HttpResponseRedirect(url)
|
||
|
|
||
|
return super().dispatch(request, *args, **kwargs)
|
||
|
|
||
|
|
||
|
class OnlyLoggedOutMixin:
|
||
|
redirect_field_name = REDIRECT_FIELD_NAME
|
||
|
|
||
|
def dispatch(self, request, *args, **kwargs):
|
||
|
if request.user.is_authenticated:
|
||
|
redirect_to = self.request.POST.get(
|
||
|
self.redirect_field_name,
|
||
|
self.request.GET.get(self.redirect_field_name, '')
|
||
|
)
|
||
|
|
||
|
url_is_safe = url_has_allowed_host_and_scheme(
|
||
|
url=redirect_to,
|
||
|
allowed_hosts=self.get_success_url_allowed_hosts(),
|
||
|
require_https=self.request.is_secure(),
|
||
|
)
|
||
|
|
||
|
url = redirect_to if url_is_safe else resolve_url(
|
||
|
settings.LOGIN_REDIRECT_URL)
|
||
|
|
||
|
if url == self.request.path:
|
||
|
raise ValueError(
|
||
|
"Redirection loop for authenticated user detected. Check that "
|
||
|
"your LOGIN_REDIRECT_URL doesn't point to a login page."
|
||
|
)
|
||
|
|
||
|
return HttpResponseRedirect(url)
|
||
|
|
||
|
return super().dispatch(request, *args, **kwargs)
|