diff --git a/src/c3nav/mesh/consumers.py b/src/c3nav/mesh/consumers.py index 2a5fa3c3..95db17c0 100644 --- a/src/c3nav/mesh/consumers.py +++ b/src/c3nav/mesh/consumers.py @@ -11,6 +11,7 @@ from asgiref.sync import async_to_sync from channels.db import database_sync_to_async from channels.exceptions import DenyConnection from channels.generic.websocket import AsyncJsonWebsocketConsumer, AsyncWebsocketConsumer +from django.conf import settings from django.db import transaction from django.utils import timezone @@ -56,7 +57,9 @@ class MeshConsumer(AsyncWebsocketConsumer): self.ota_chunks_available_condition = asyncio.Condition() async def connect(self): - # todo: auth + self.headers = dict(self.scope["headers"]) + if self.headers[b'authorization'].strip() != b'Bearer '+settings.SECRET_MESH_KEY.encode(): + raise DenyConnection # await self.log_text(None, "new mesh websocket connection") await self.accept() diff --git a/src/c3nav/settings.py b/src/c3nav/settings.py index f02ca0ea..672d0364 100644 --- a/src/c3nav/settings.py +++ b/src/c3nav/settings.py @@ -123,6 +123,23 @@ if not SECRET_TILE_KEY: os.chown(SECRET_TILE_FILE, os.getuid(), os.getgid()) f.write(SECRET_TILE_KEY) +SECRET_MESH_KEY = config.get('c3nav', 'mesh_secret', fallback=None) +if not SECRET_MESH_KEY: + SECRET_MESH_FILE = config.get('c3nav', 'mesh_secret_file', fallback=None) + if SECRET_MESH_FILE: + SECRET_MESH_FILE = Path(SECRET_MESH_FILE) + else: + SECRET_MESH_FILE = DATA_DIR / '.mesh_secret' + if SECRET_MESH_FILE.exists(): + with open(SECRET_MESH_FILE, 'r') as f: + SECRET_MESH_KEY = f.read().strip() + else: + SECRET_MESH_KEY = get_random_string(50, string.printable) + with open(SECRET_MESH_FILE, 'w') as f: + os.chmod(SECRET_MESH_FILE, 0o600) + os.chown(SECRET_MESH_FILE, os.getuid(), os.getgid()) + f.write(SECRET_MESH_KEY) + # Adjustable settings debug_fallback = "runserver" in sys.argv