forked from wiktor/spejstore-new
auth: cleanup
This commit is contained in:
parent
156df0a8a5
commit
38c7245a3f
|
@ -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
|
||||||
|
|
|
@ -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(",")
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue