From 0199ac962afe15569bcc86ad9e094e52f8efd032 Mon Sep 17 00:00:00 2001 From: Benedikt Willi Date: Thu, 8 Jun 2023 10:19:27 +0200 Subject: [PATCH] Added Django 4.1 & 4.2 support --- .github/workflows/django.yml | 24 ++++++++++++++++++++ tos/middleware.py | 43 ++++++++++++++++++++++++++++++++++++ tos/views.py | 9 ++------ 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 9f43293..c396913 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -26,6 +26,12 @@ jobs: - python-version: "3.8" django-version: Django==4.0 + - python-version: "3.8" + django-version: Django==4.1 + + - python-version: "3.8" + django-version: Django==4.2 + - python-version: "3.9" django-version: Django==2.2 @@ -35,12 +41,30 @@ jobs: - python-version: "3.9" django-version: Django==4.0 + - python-version: "3.9" + django-version: Django==3.1 + + - python-version: "3.9" + django-version: Django==4.2 + - python-version: "3.10" django-version: Django==3.2 - python-version: "3.10" django-version: Django==4.0 + - python-version: "3.10" + django-version: Django==3.1 + + - python-version: "3.10" + django-version: Django==4.2 + + - python-version: "3.11" + django-version: Django==4.1 + + - python-version: "3.11" + django-version: Django==4.2 + steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} diff --git a/tos/middleware.py b/tos/middleware.py index aac4678..0d49f72 100644 --- a/tos/middleware.py +++ b/tos/middleware.py @@ -22,6 +22,49 @@ class UserAgreementMiddleware(MiddlewareMixin): def __init__(self, get_response=None): self.get_response = get_response + def __call__(self, request): + # Check if we should skip TOS checks without hitting the cache or database + if self.should_fast_skip(request): + return self.get_response(request) + + # Grab the user ID from the session so we avoid hitting the database + # for the user object. + # NOTE: We use the user ID because it's not user-settable and it won't + # ever change (usernames and email addresses can change) + user_id = request.session['_auth_user_id'] + + # Get the cache prefix + key_version = cache.get('django:tos:key_version') + + # Skip if the user is allowed to skip - for instance, if the user is an + # admin or a staff member + if cache.get(f'django:tos:skip_tos_check:{user_id}', False, version=key_version): + return self.get_response(request) + + # Ping the cache for the user agreement + user_agreed = cache.get(f'django:tos:agreed:{user_id}', None, version=key_version) + + # If the cache is missing this user + if user_agreed is None: + # Check the database and cache the result + user_agreed = self.get_and_cache_agreement_from_db(user_id, key_version) + + if not user_agreed: + # Confirm view uses these session keys. Non-middleware flow sets them in login view, + # so we need to set them here. + request.session['tos_user'] = user_id + request.session['tos_backend'] = request.session['_auth_user_backend'] + + response = HttpResponseRedirect('{0}?{1}={2}'.format( + tos_check_url, + REDIRECT_FIELD_NAME, + request.path_info, + )) + add_never_cache_headers(response) + return response + + return self.get_response(request) + def process_request(self, request): if self.should_fast_skip(request): return None diff --git a/tos/views.py b/tos/views.py index bba44ab..b0143c3 100644 --- a/tos/views.py +++ b/tos/views.py @@ -1,14 +1,12 @@ import re -from django import VERSION as DJANGO_VERSION from django.conf import settings from django.contrib import messages from django.contrib.auth import login as auth_login from django.contrib.auth import REDIRECT_FIELD_NAME from django.contrib.auth import get_user_model from django.contrib.auth.forms import AuthenticationForm -from django.contrib.sites.models import Site -from django.contrib.sites.requests import RequestSite +from django.contrib.sites.shortcuts import get_current_site from django.core.cache import caches from django.http import HttpResponseRedirect from django.shortcuts import render @@ -136,10 +134,7 @@ def login(request, template_name='registration/login.html', request.session.set_test_cookie() - if Site._meta.installed: - current_site = Site.objects.get_current() - else: - current_site = RequestSite(request) + current_site = get_current_site(request) context = { 'form': form,