auth: cleanup

This commit is contained in:
Dariusz Niemczyk 2023-09-09 19:26:36 +02:00
parent 156df0a8a5
commit 38c7245a3f
No known key found for this signature in database
4 changed files with 28 additions and 36 deletions

View File

@ -14,3 +14,4 @@ services:
# - SPEJSTORE_MEDIA_ROOT= # - SPEJSTORE_MEDIA_ROOT=
# - SPEJSTORE_REQUIRE_AUTH=true # - SPEJSTORE_REQUIRE_AUTH=true
- SPEJSTORE_OAUTH_REDIRECT_IS_HTTPS=false - SPEJSTORE_OAUTH_REDIRECT_IS_HTTPS=false
- SPEJSTORE_PROXY_TRUSTED_IPS=172.21.37.1

View File

@ -220,8 +220,5 @@ SOCIAL_AUTH_JSONFIELD_ENABLED = True
LABEL_API = env("LABEL_API", "http://label.waw.hackerspace.pl:4567") LABEL_API = env("LABEL_API", "http://label.waw.hackerspace.pl:4567")
LOGIN_URL = "/admin/login/" LOGIN_URL = "/admin/login/"
# HSWAW lan # Local LAN address space
LAN_ALLOWED_ADDRESS_SPACE = env("LAN_ALLOWED_ADDRESS_SPACE", "10.8.0.0/16") LAN_ALLOWED_ADDRESS_SPACE = env("LAN_ALLOWED_ADDRESS_SPACE", "")
LAN_ALLOWED_HEADER = env("LAN_ALLOWED_HEADER", "X-LAN-ALLOWED")
PROXY_TRUSTED_IPS = env("PROXY_TRUSTED_IPS", "172.21.37.1").split(",")

View File

@ -4,9 +4,6 @@ from rest_framework import exceptions
from rest_framework.authentication import SessionAuthentication from rest_framework.authentication import SessionAuthentication
from spejstore.settings import ( from spejstore.settings import (
LAN_ALLOWED_ADDRESS_SPACE, 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): def has_permission(request):
if PROD: # We don't care if address space is undefined
client_ip = get_ip_from_request(request) if LAN_ALLOWED_ADDRESS_SPACE == '':
if client_ip is None: return (True, '')
# This should only happen on localhost env when fiddling with code. client_ip = get_ip_from_request(request)
# It's technically impossible to get there with proper headers. if client_ip is None:
raise exceptions.AuthenticationFailed("Unauthorized: no ip detected?") # This should only happen on localhost env when fiddling with code.
# Make sure that we need to check PROXY_TRUSTED_IPS here # It's technically impossible to get there with proper headers.
if len(PROXY_TRUSTED_IPS) > 0: return (False, "Unauthorized: no ip detected?")
if request.META["REMOTE_ADDR"] not in PROXY_TRUSTED_IPS: in_local_space = ipaddress.IPv4Address(client_ip) in ipaddress.IPv4Network(
raise exceptions.AuthenticationFailed( LAN_ALLOWED_ADDRESS_SPACE
"Unauthorized: request is not coming from the PROXY_TRUSTED_IPS machine" )
) if not in_local_space:
return ipaddress.IPv4Address(client_ip) in ipaddress.IPv4Network( return (False, "Unauthorized: " + client_ip + " not in subnet of " + LAN_ALLOWED_ADDRESS_SPACE)
LAN_ALLOWED_ADDRESS_SPACE return (True, '')
)
else:
return True
class LanAuthentication(SessionAuthentication): class LanAuthentication(SessionAuthentication):
def authenticate(self, request): def authenticate(self, request):
is_session_authorized = super().authenticate(request) is_session_authorized = super().authenticate(request)
if is_session_authorized: if is_session_authorized:
return is_session_authorized return is_session_authorized
is_authorized = has_permission(request) is_authorized, error_message = has_permission(request)
if is_authorized: if is_authorized:
user = getattr(request._request, "user", None) user = getattr(request._request, "user", None)
return (user, "authorized") return (user, "authorized")
else: else:
raise exceptions.AuthenticationFailed( raise exceptions.AuthenticationFailed(
"Unauthorized: not in subnet of " + LAN_ALLOWED_ADDRESS_SPACE error_message
) )
def authenticate_header(self, request):
return LAN_ALLOWED_HEADER

View File

@ -1,22 +1,25 @@
from storage.authentication import has_permission from storage.authentication import has_permission
from django.http import HttpResponseRedirect 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): def is_authorized_or_in_lan_middleware(get_response):
# One-time configuration and initialization. # One-time configuration and initialization.
login_paths_to_ignore = [ login_paths_to_ignore = [
"/admin/login", "/login",
"/static", LOGIN_URL[:-1],
STATIC_URL[:-1],
MEDIA_URL[:-1],
"/admin/static", "/admin/static",
"/complete", "/complete",
"/favicon.ico", "/favicon.ico",
"/api", "/api/1",
] ]
def middleware(request): def middleware(request):
if request.user.is_authenticated: if request.user.is_authenticated:
return get_response(request) return get_response(request)
is_within_lan = has_permission(request) is_within_lan, error_message = has_permission(request)
if is_within_lan: if is_within_lan:
return get_response(request) return get_response(request)
else: else:
@ -24,6 +27,6 @@ def is_authorized_or_in_lan_middleware(get_response):
if request.path.startswith(login_path): if request.path.startswith(login_path):
return get_response(request) return get_response(request)
else: else:
return HttpResponseRedirect("/admin/login") raise PermissionDenied()
return middleware return middleware