From 2a306f44c1e20526b910ea3819ec4c3e2261d400 Mon Sep 17 00:00:00 2001 From: eyjhb Date: Thu, 2 Jan 2025 11:51:46 +0100 Subject: [PATCH] adds support for proxy auth header Useful if you have authentication in front of wger, and want to use that instead of wgers authentication/signup methods. --- wger/settings.tpl | 4 ++++ wger/utils/middleware.py | 17 +++++++++++++- wger/utils/tests/test_auth_proxy_header.py | 26 ++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 wger/utils/tests/test_auth_proxy_header.py diff --git a/wger/settings.tpl b/wger/settings.tpl index b57ffa858..d6ca2b50c 100644 --- a/wger/settings.tpl +++ b/wger/settings.tpl @@ -15,6 +15,10 @@ WGER_SETTINGS["ALLOW_GUEST_USERS"] = True WGER_SETTINGS["ALLOW_UPLOAD_VIDEOS"] = False WGER_SETTINGS["MIN_ACCOUNT_AGE_TO_TRUST"] = 21 # in days WGER_SETTINGS["EXERCISE_CACHE_TTL"] = 3600 # in seconds +# can be used if there is authentication in front of wger, e.g. +# if authelia is used to authenticate the users. Users will be +# created with this username. +# WGER_SETTINGS["AUTH_PROXY_HEADER"] = "Remote-User" DATABASES = {{ 'default': {{ diff --git a/wger/utils/middleware.py b/wger/utils/middleware.py index fdde69f6a..f7ea81bdf 100644 --- a/wger/utils/middleware.py +++ b/wger/utils/middleware.py @@ -22,6 +22,7 @@ from django.conf import settings from django.contrib import auth from django.contrib.auth import login as django_login +from django.contrib.auth.models import User from django.utils.deprecation import MiddlewareMixin from django.utils.functional import SimpleLazyObject @@ -62,8 +63,22 @@ def get_user(request): if not request.session.get('has_demo_data'): request.session['has_demo_data'] = False + # if auth proxy header is setup, then create the user + # as authentication has already happened. + auth_proxy_header = settings.WGER_SETTINGS.get("AUTH_PROXY_HEADER") + if auth_proxy_header: + username = request.META.get(auth_proxy_header) + if username: + user_query = User.objects.filter(username=username) + if user_query.exists(): + user = user_query.first() + else: + user = User.objects.create_user(username) + user.save() + + django_login(request, user, backend='django.contrib.auth.backends.ModelBackend') # Django didn't find a user, so create one now - if ( + elif ( settings.WGER_SETTINGS['ALLOW_GUEST_USERS'] and request.method == 'GET' and create_user diff --git a/wger/utils/tests/test_auth_proxy_header.py b/wger/utils/tests/test_auth_proxy_header.py new file mode 100644 index 000000000..5f09ffc68 --- /dev/null +++ b/wger/utils/tests/test_auth_proxy_header.py @@ -0,0 +1,26 @@ +# Django +from django.urls import reverse + +# wger +from wger.core.tests.base_testcase import WgerTestCase + + +class ProxyAuthHeaderTestCase(WgerTestCase): + """ + Tests using proxy auth for authentication + """ + + def test_basic_auth_proxy_header(self): + """ + Tests that the proxy auth header works for authenticating + the user + """ + with self.settings( + WGER_SETTINGS={ + "AUTH_PROXY_HEADER": "Remote-User", + "ALLOW_REGISTRATION": False, + "ALLOW_GUEST_USERS": False, + } + ): + response = self.client.get(reverse("core:dashboard"), remote_user="testuser") + self.assertEqual(response.status_code, 200)