auth: cleanup

pull/1/head
palid 2023-09-09 19:26:36 +02:00
parent 156df0a8a5
commit 38c7245a3f
Signed by: palid
SSH Key Fingerprint: SHA256:Mus3wCd2x6nxtARI0DpWGT7lIWbNy3R90BVDg0j35PI
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
if LAN_ALLOWED_ADDRESS_SPACE == '':
return (True, '')
client_ip = get_ip_from_request(request) client_ip = get_ip_from_request(request)
if client_ip is None: if client_ip is None:
# This should only happen on localhost env when fiddling with code. # This should only happen on localhost env when fiddling with code.
# It's technically impossible to get there with proper headers. # It's technically impossible to get there with proper headers.
raise exceptions.AuthenticationFailed("Unauthorized: no ip detected?") return (False, "Unauthorized: no ip detected?")
# Make sure that we need to check PROXY_TRUSTED_IPS here in_local_space = ipaddress.IPv4Address(client_ip) in ipaddress.IPv4Network(
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 LAN_ALLOWED_ADDRESS_SPACE
) )
else: if not in_local_space:
return True return (False, "Unauthorized: " + client_ip + " not in subnet of " + LAN_ALLOWED_ADDRESS_SPACE)
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