Add an option to completely disable driver

This commit is contained in:
2022-07-11 20:56:31 +02:00
parent 49d28b176e
commit 47b4b2915b
4 changed files with 47 additions and 7 deletions

View File

@@ -7,6 +7,14 @@ from driver.models import DriverConfiguration
@admin.register(DriverConfiguration) @admin.register(DriverConfiguration)
class DriverConfigurationAdmin(SingletonModelAdmin): class DriverConfigurationAdmin(SingletonModelAdmin):
fieldsets = ( fieldsets = (
(
"General configuration",
{
"fields": (
"enabled",
)
},
),
( (
"Remote DCC-EX configuration", "Remote DCC-EX configuration",
{ {

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.0.6 on 2022-07-11 18:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('driver', '0004_alter_driverconfiguration_remote_host'),
]
operations = [
migrations.AddField(
model_name='driverconfiguration',
name='enabled',
field=models.BooleanField(default=False),
),
]

View File

@@ -1,10 +1,11 @@
from django.db import models from django.db import models
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from ipaddress import IPv4Address, IPv4Network from ipaddress import IPv4Network
from solo.models import SingletonModel from solo.models import SingletonModel
class DriverConfiguration(SingletonModel): class DriverConfiguration(SingletonModel):
enabled = models.BooleanField(default=False)
remote_host = models.GenericIPAddressField( remote_host = models.GenericIPAddressField(
protocol="IPv4", default="192.168.4.1" protocol="IPv4", default="192.168.4.1"
) )

View File

@@ -34,9 +34,22 @@ def addresschecker(f):
return addresslookup return addresslookup
class IsEnabled(BasePermission):
def has_permission(self, request, view):
config = DriverConfiguration.get_solo()
# if driver is disabled, block all connections
if not config.enabled:
raise Http404
return True
class Firewall(BasePermission): class Firewall(BasePermission):
def has_permission(self, request, view): def has_permission(self, request, view):
config = DriverConfiguration.get_solo() config = DriverConfiguration.get_solo()
# if network is not configured, accept only read ops
if not config.network: if not config.network:
return request.method in SAFE_METHODS return request.method in SAFE_METHODS
@@ -61,7 +74,7 @@ class Test(APIView):
""" """
parser_classes = [PlainTextParser] parser_classes = [PlainTextParser]
permission_classes = [IsAuthenticated | Firewall] permission_classes = [IsEnabled & IsAuthenticated | Firewall]
def get(self, request): def get(self, request):
response = Connector().passthrough("<s>") response = Connector().passthrough("<s>")
@@ -76,7 +89,7 @@ class SendCommand(APIView):
""" """
parser_classes = [PlainTextParser] parser_classes = [PlainTextParser]
permission_classes = [IsAuthenticated | Firewall] permission_classes = [IsEnabled & IsAuthenticated | Firewall]
def put(self, request): def put(self, request):
data = request.data data = request.data
@@ -101,7 +114,7 @@ class Function(APIView):
Send "Function" commands to a valid DCC address Send "Function" commands to a valid DCC address
""" """
permission_classes = [IsAuthenticated | Firewall] permission_classes = [IsEnabled & IsAuthenticated | Firewall]
def put(self, request, address): def put(self, request, address):
serializer = FunctionSerializer(data=request.data) serializer = FunctionSerializer(data=request.data)
@@ -118,7 +131,7 @@ class Cab(APIView):
Send "Cab" commands to a valid DCC address Send "Cab" commands to a valid DCC address
""" """
permission_classes = [IsAuthenticated | Firewall] permission_classes = [IsEnabled & IsAuthenticated | Firewall]
def put(self, request, address): def put(self, request, address):
serializer = CabSerializer(data=request.data) serializer = CabSerializer(data=request.data)
@@ -134,7 +147,7 @@ class Infra(APIView):
Send "Infra" commands to a valid DCC address Send "Infra" commands to a valid DCC address
""" """
permission_classes = [IsAuthenticated | Firewall] permission_classes = [IsEnabled & IsAuthenticated | Firewall]
def put(self, request): def put(self, request):
serializer = InfraSerializer(data=request.data) serializer = InfraSerializer(data=request.data)
@@ -150,7 +163,7 @@ class Emergency(APIView):
Send an "Emergency" stop, no matter the HTTP method used Send an "Emergency" stop, no matter the HTTP method used
""" """
permission_classes = [IsAuthenticated | Firewall] permission_classes = [IsEnabled & IsAuthenticated | Firewall]
def put(self, request): def put(self, request):
Connector().emergency() Connector().emergency()