From 38c7245a3fcc7bc315e960c76cac7e263f531998 Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk Date: Sat, 9 Sep 2023 19:26:36 +0200 Subject: [PATCH] auth: cleanup --- docker-compose.dev-override.yml | 1 + spejstore/settings.py | 7 ++---- storage/authentication.py | 41 +++++++++++++-------------------- storage/middleware.py | 15 +++++++----- 4 files changed, 28 insertions(+), 36 deletions(-) diff --git a/docker-compose.dev-override.yml b/docker-compose.dev-override.yml index 8db47a0..ffa8675 100644 --- a/docker-compose.dev-override.yml +++ b/docker-compose.dev-override.yml @@ -14,3 +14,4 @@ services: # - SPEJSTORE_MEDIA_ROOT= # - SPEJSTORE_REQUIRE_AUTH=true - SPEJSTORE_OAUTH_REDIRECT_IS_HTTPS=false + - SPEJSTORE_PROXY_TRUSTED_IPS=172.21.37.1 diff --git a/spejstore/settings.py b/spejstore/settings.py index dbeab2c..c27d15a 100644 --- a/spejstore/settings.py +++ b/spejstore/settings.py @@ -220,8 +220,5 @@ SOCIAL_AUTH_JSONFIELD_ENABLED = True LABEL_API = env("LABEL_API", "http://label.waw.hackerspace.pl:4567") LOGIN_URL = "/admin/login/" -# HSWAW lan -LAN_ALLOWED_ADDRESS_SPACE = env("LAN_ALLOWED_ADDRESS_SPACE", "10.8.0.0/16") - -LAN_ALLOWED_HEADER = env("LAN_ALLOWED_HEADER", "X-LAN-ALLOWED") -PROXY_TRUSTED_IPS = env("PROXY_TRUSTED_IPS", "172.21.37.1").split(",") +# Local LAN address space +LAN_ALLOWED_ADDRESS_SPACE = env("LAN_ALLOWED_ADDRESS_SPACE", "") diff --git a/storage/authentication.py b/storage/authentication.py index d61920c..3deed98 100644 --- a/storage/authentication.py +++ b/storage/authentication.py @@ -4,9 +4,6 @@ from rest_framework import exceptions from rest_framework.authentication import SessionAuthentication from spejstore.settings import ( LAN_ALLOWED_ADDRESS_SPACE, - LAN_ALLOWED_HEADER, - PROD, - PROXY_TRUSTED_IPS, ) @@ -41,38 +38,32 @@ def get_ip_from_request(request): 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 - + # We don't care if address space is undefined + if LAN_ALLOWED_ADDRESS_SPACE == '': + return (True, '') + 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. + return (False, "Unauthorized: no ip detected?") + in_local_space = ipaddress.IPv4Address(client_ip) in ipaddress.IPv4Network( + LAN_ALLOWED_ADDRESS_SPACE + ) + if not in_local_space: + return (False, "Unauthorized: " + client_ip + " not in subnet of " + LAN_ALLOWED_ADDRESS_SPACE) + return (True, '') class LanAuthentication(SessionAuthentication): def authenticate(self, request): is_session_authorized = super().authenticate(request) if is_session_authorized: return is_session_authorized - is_authorized = has_permission(request) + is_authorized, error_message = has_permission(request) if is_authorized: user = getattr(request._request, "user", None) return (user, "authorized") else: raise exceptions.AuthenticationFailed( - "Unauthorized: not in subnet of " + LAN_ALLOWED_ADDRESS_SPACE + error_message ) - def authenticate_header(self, request): - return LAN_ALLOWED_HEADER diff --git a/storage/middleware.py b/storage/middleware.py index f95dfa8..abc0ec6 100644 --- a/storage/middleware.py +++ b/storage/middleware.py @@ -1,22 +1,25 @@ from storage.authentication import has_permission from django.http import HttpResponseRedirect - +from spejstore.settings import STATIC_URL, MEDIA_URL, LOGIN_URL +from django.core.exceptions import PermissionDenied def is_authorized_or_in_lan_middleware(get_response): # One-time configuration and initialization. login_paths_to_ignore = [ - "/admin/login", - "/static", + "/login", + LOGIN_URL[:-1], + STATIC_URL[:-1], + MEDIA_URL[:-1], "/admin/static", "/complete", "/favicon.ico", - "/api", + "/api/1", ] def middleware(request): if request.user.is_authenticated: return get_response(request) - is_within_lan = has_permission(request) + is_within_lan, error_message = has_permission(request) if is_within_lan: return get_response(request) else: @@ -24,6 +27,6 @@ def is_authorized_or_in_lan_middleware(get_response): if request.path.startswith(login_path): return get_response(request) else: - return HttpResponseRedirect("/admin/login") + raise PermissionDenied() return middleware