From dfaa4c3359583d793e0f94bbffa1d262b59a7ba9 Mon Sep 17 00:00:00 2001 From: George Hickman Date: Mon, 16 Mar 2026 16:39:04 +0000 Subject: [PATCH] Add session_login function (#5955) * Add session_login function * Make helper do more things and use it --------- Co-authored-by: Raphael Michel --- src/pretix/control/views/auth.py | 28 +++++++--------------------- src/pretix/control/views/user.py | 9 +++------ src/pretix/helpers/security.py | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/pretix/control/views/auth.py b/src/pretix/control/views/auth.py index be62d1ec1..143d3cfcc 100644 --- a/src/pretix/control/views/auth.py +++ b/src/pretix/control/views/auth.py @@ -41,9 +41,7 @@ from urllib.parse import quote, urljoin, urlparse import webauthn from django.conf import settings from django.contrib import messages -from django.contrib.auth import ( - authenticate, login as auth_login, logout as auth_logout, -) +from django.contrib.auth import authenticate, logout as auth_logout from django.contrib.auth.tokens import default_token_generator from django.core.exceptions import PermissionDenied from django.db import transaction @@ -67,7 +65,7 @@ from pretix.base.forms.auth import ( from pretix.base.metrics import pretix_failed_logins, pretix_successful_logins from pretix.base.models import TeamInvite, U2FDevice, User, WebAuthnDevice from pretix.helpers.http import get_client_ip, redirect_to_url -from pretix.helpers.security import handle_login_source +from pretix.helpers.security import handle_login_source, session_login logger = logging.getLogger(__name__) @@ -79,12 +77,12 @@ def process_login(request, user, keep_logged_in): :return: This method returns a ``HttpResponse``. """ - request.session['pretix_auth_long_session'] = settings.PRETIX_LONG_SESSIONS and keep_logged_in next_url = get_auth_backends()[user.auth_backend].get_next_url(request) if user.require_2fa: logger.info(f"Backend login redirected to 2FA for user {user.pk}.") request.session['pretix_auth_2fa_user'] = user.pk request.session['pretix_auth_2fa_time'] = str(int(time.time())) + request.session['pretix_auth_long_session'] = settings.PRETIX_LONG_SESSIONS and keep_logged_in twofa_url = reverse('control:auth.login.2fa') if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None): twofa_url += '?next=' + quote(next_url) @@ -93,10 +91,7 @@ def process_login(request, user, keep_logged_in): logger.info(f"Backend login successful for user {user.pk}.") pretix_successful_logins.inc(1) handle_login_source(user, request) - auth_login(request, user) - t = int(time.time()) - request.session['pretix_auth_login_time'] = t - request.session['pretix_auth_last_used'] = t + session_login(request, user, keep_logged_in) if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None): return redirect_to_url(next_url) return redirect('control:index') @@ -221,11 +216,7 @@ def register(request): ) user = authenticate(request=request, email=user.email, password=form.cleaned_data['password']) user.log_action('pretix.control.auth.user.created', user=user) - auth_login(request, user) - request.session['pretix_auth_login_time'] = int(time.time()) - request.session['pretix_auth_long_session'] = ( - settings.PRETIX_LONG_SESSIONS and form.cleaned_data.get('keep_logged_in', False) - ) + session_login(request, user, form.cleaned_data.get('keep_logged_in', False)) return redirect('control:index') else: form = RegistrationForm() @@ -284,11 +275,7 @@ def invite(request, token): ) user = authenticate(request=request, email=user.email, password=form.cleaned_data['password']) user.log_action('pretix.control.auth.user.created', user=user) - auth_login(request, user) - request.session['pretix_auth_login_time'] = int(time.time()) - request.session['pretix_auth_long_session'] = ( - settings.PRETIX_LONG_SESSIONS and form.cleaned_data.get('keep_logged_in', False) - ) + session_login(request, user, form.cleaned_data.get('keep_logged_in', False)) inv.team.members.add(request.user) inv.team.log_action( @@ -546,8 +533,7 @@ class Login2FAView(TemplateView): logger.info(f"Backend login successful for user {self.user.pk} with 2FA.") pretix_successful_logins.inc(1) handle_login_source(self.user, request) - auth_login(request, self.user) - request.session['pretix_auth_login_time'] = int(time.time()) + session_login(request, self.user, request.session["pretix_auth_long_session"]) del request.session['pretix_auth_2fa_user'] del request.session['pretix_auth_2fa_time'] if "next" in request.GET and url_has_allowed_host_and_scheme(request.GET.get("next"), allowed_hosts=None): diff --git a/src/pretix/control/views/user.py b/src/pretix/control/views/user.py index d13e6b4ee..315b1ef04 100644 --- a/src/pretix/control/views/user.py +++ b/src/pretix/control/views/user.py @@ -80,6 +80,7 @@ from pretix.control.permissions import ( ) from pretix.control.views.auth import get_u2f_appid, get_webauthn_rp_id from pretix.helpers.http import redirect_to_url +from pretix.helpers.security import session_reauth from pretix.helpers.u2f import websafe_encode REAL_DEVICE_TYPES = (TOTPDevice, WebAuthnDevice, U2FDevice) @@ -159,9 +160,7 @@ class ReauthView(TemplateView): valid = valid or self.form.is_valid() if valid: - t = int(time.time()) - request.session['pretix_auth_login_time'] = t - request.session['pretix_auth_last_used'] = t + session_reauth(request) next_url = get_auth_backends()[request.user.auth_backend].get_next_url(request) if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None): return redirect_to_url(next_url) @@ -175,9 +174,7 @@ class ReauthView(TemplateView): u = backend.request_authenticate(request) if u and u == request.user: next_url = backend.get_next_url(request) - t = int(time.time()) - request.session['pretix_auth_login_time'] = t - request.session['pretix_auth_last_used'] = t + session_reauth(request) if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None): return redirect_to_url(next_url) return redirect(reverse('control:index')) diff --git a/src/pretix/helpers/security.py b/src/pretix/helpers/security.py index 2e5b545b5..6a67bbc69 100644 --- a/src/pretix/helpers/security.py +++ b/src/pretix/helpers/security.py @@ -24,6 +24,7 @@ import logging import time from django.conf import settings +from django.contrib.auth import login as auth_login from django.contrib.gis.geoip2 import GeoIP2 from django.core.cache import cache from django.utils.timezone import now @@ -174,3 +175,17 @@ def handle_login_source(user, request): user=user, locale=user.locale ) + + +def session_login(request, user, keep_logged_in=False): + auth_login(request, user) + session_reauth(request) + request.session["pretix_auth_long_session"] = ( + settings.PRETIX_LONG_SESSIONS and keep_logged_in + ) + + +def session_reauth(request): + t = int(time.time()) + request.session['pretix_auth_login_time'] = t + request.session['pretix_auth_last_used'] = t