django: force auth for all requests

This commit is contained in:
Dariusz Niemczyk 2023-08-25 21:06:01 +02:00
parent 401fcc088d
commit 15bf813b04
No known key found for this signature in database
3 changed files with 46 additions and 18 deletions

View File

@ -63,6 +63,7 @@ MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
"django.middleware.cache.UpdateCacheMiddleware",
"storage.middleware.is_authorized_or_in_lan_middleware",
"django.middleware.gzip.GZipMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",

View File

@ -24,7 +24,7 @@ headers_to_check_for_ip = [
def get_request_meta(request, key):
value = request.META.get(key, request).strip()
value = request.META.get(key, "")
if value == "":
return None
return value
@ -40,6 +40,26 @@ def get_ip_from_request(request):
return None
def has_permission(request):
if PROD:
client_ip = get_ip_from_request(request)
if client_ip is None:
# This should only happen on localhost env when fiddling with code.
# It's technically impossible to get there with proper headers.
raise exceptions.AuthenticationFailed("Unauthorized: no ip detected?")
# Make sure that we need to check PROXY_TRUSTED_IPS here
if len(PROXY_TRUSTED_IPS) > 0:
if request.META["REMOTE_ADDR"] not in PROXY_TRUSTED_IPS:
raise exceptions.AuthenticationFailed(
"Unauthorized: request is not coming from the PROXY_TRUSTED_IPS machine"
)
return ipaddress.IPv4Address(client_ip) in ipaddress.IPv4Network(
LAN_ALLOWED_ADDRESS_SPACE
)
else:
return True
class LanAuthentication(SessionAuthentication):
def authenticate(self, request):
is_session_authorized = super().authenticate(request)
@ -56,20 +76,3 @@ class LanAuthentication(SessionAuthentication):
def authenticate_header(self, request):
return LAN_ALLOWED_HEADER
def has_permission(self, request):
if PROD:
client_ip = get_ip_from_request(request)
if client_ip is None:
raise exceptions.AuthenticationFailed("Unauthorized: no ip detected?")
# Make sure that we need to check PROXY_TRUSTED_IPS here
if len(PROXY_TRUSTED_IPS) > 0:
if request.META["REMOTE_ADDR"] not in PROXY_TRUSTED_IPS:
raise exceptions.AuthenticationFailed(
"Unauthorized: request is not coming from the PROXY_TRUSTED_IPS machine"
)
return ipaddress.IPv4Address(client_ip) in ipaddress.IPv4Network(
LAN_ALLOWED_ADDRESS_SPACE
)
else:
return True

24
storage/middleware.py Normal file
View File

@ -0,0 +1,24 @@
from django.core.exceptions import PermissionDenied
from storage.authentication import has_permission
def is_authorized_or_in_lan_middleware(get_response):
# One-time configuration and initialization.
def middleware(request):
# Code to be executed for each request before
# the view (and later middleware) are called.
response = get_response(request)
if request.user.is_authenticated:
return response
is_within_lan = has_permission(request)
if is_within_lan:
return response
else:
raise PermissionDenied()
# Code to be executed for each request/response after
# the view is called.
return middleware