diff --git a/moonraker/components/authorization.py b/moonraker/components/authorization.py index c0a2570..d90b068 100644 --- a/moonraker/components/authorization.py +++ b/moonraker/components/authorization.py @@ -615,6 +615,13 @@ class Authorization: ) from e return user_info + def validate_api_key(self, api_key: str) -> Dict[str, Any]: + if not self.enable_api_key: + raise self.server.error("API Key authentication is disabled", 401) + if api_key and api_key == self.api_key: + return self.users[API_USER] + raise self.server.error("Invalid API Key", 401) + def _load_private_key(self, secret: str) -> Signer: try: key = Signer(bytes.fromhex(secret)) diff --git a/moonraker/websockets.py b/moonraker/websockets.py index 171d551..a5017d8 100644 --- a/moonraker/websockets.py +++ b/moonraker/websockets.py @@ -376,7 +376,10 @@ class WebsocketManager(APITransport): async def _handle_identify(self, args: Dict[str, Any]) -> Dict[str, int]: sc: BaseSocketClient = args["_socket_"] - sc.authenticate(token=args.get("access_token", None)) + sc.authenticate( + token=args.get("access_token", None), + api_key=args.get("api_key", None) + ) if sc.identified: raise self.server.error( f"Connection already identified: {sc.client_data}" @@ -569,15 +572,20 @@ class BaseSocketClient(Subscribable): self.queue_busy = True self.eventloop.register_callback(self._write_messages) - def authenticate(self, path: str = "", token: Optional[str] = None) -> None: + def authenticate( + self, path: str = "", + token: Optional[str] = None, + api_key: Optional[str] = None + ) -> None: if not self._need_auth: return auth: AuthComp = self.server.lookup_component("authorization", None) if auth is None: return if token is not None: - user_info = auth.validate_jwt(token) - self.user_info = user_info + self.user_info = auth.validate_jwt(token) + elif api_key is not None: + self.user_info = auth.validate_api_key(api_key) elif not auth.is_path_permitted(path): raise self.server.error("Unauthorized", 401)