1
0
mirror of https://github.com/esphome/esphome.git synced 2025-02-12 07:58:17 +00:00
This commit is contained in:
J. Nick Koston 2023-11-18 09:20:57 -06:00
parent d46188ecda
commit d0baa20728
No known key found for this signature in database
2 changed files with 19 additions and 13 deletions

View File

@ -3,7 +3,7 @@ from __future__ import annotations
import hmac import hmac
import os import os
from pathlib import Path from pathlib import Path
from typing import Any
from esphome.core import CORE from esphome.core import CORE
from esphome.helpers import get_bool_env from esphome.helpers import get_bool_env
@ -69,7 +69,8 @@ class DashboardSettings:
# Compare password in constant running time (to prevent timing attacks) # Compare password in constant running time (to prevent timing attacks)
return hmac.compare_digest(self.password_hash, password_hash(password)) return hmac.compare_digest(self.password_hash, password_hash(password))
def rel_path(self, *args): def rel_path(self, *args: Any) -> str:
"""Return a path relative to the ESPHome config folder."""
joined_path = os.path.join(self.config_dir, *args) joined_path = os.path.join(self.config_dir, *args)
# Raises ValueError if not relative to ESPHome config folder # Raises ValueError if not relative to ESPHome config folder
Path(joined_path).resolve().relative_to(self.absolute_config_dir) Path(joined_path).resolve().relative_to(self.absolute_config_dir)

View File

@ -525,9 +525,19 @@ class DownloadListRequestHandler(BaseHandler):
class DownloadBinaryRequestHandler(BaseHandler): class DownloadBinaryRequestHandler(BaseHandler):
def _load_file(self, path: str, compressed: bool) -> bytes:
"""Load a file from disk and compress it if requested."""
with open(path, "rb") as f:
data = f.read()
if compressed:
return gzip.compress(data, 9)
return data
@authenticated @authenticated
@bind_config @bind_config
async def get(self, configuration=None): async def get(self, configuration: str | None = None):
"""Download a binary file."""
loop = asyncio.get_running_loop()
compressed = self.get_argument("compressed", "0") == "1" compressed = self.get_argument("compressed", "0") == "1"
storage_path = ext_storage_path(configuration) storage_path = ext_storage_path(configuration)
@ -584,11 +594,8 @@ class DownloadBinaryRequestHandler(BaseHandler):
self.send_error(404) self.send_error(404)
return return
with open(path, "rb") as f: data = await loop.run_in_executor(None, self._load_file, path, compressed)
data = f.read() self.write(data)
if compressed:
data = gzip.compress(data, 9)
self.write(data)
self.finish() self.finish()
@ -748,13 +755,10 @@ class EditRequestHandler(BaseHandler):
@authenticated @authenticated
@bind_config @bind_config
async def get(self, configuration: str | None = None): async def get(self, configuration: str | None = None):
"""Get the content of a file."""
loop = asyncio.get_running_loop() loop = asyncio.get_running_loop()
filename = settings.rel_path(configuration) filename = settings.rel_path(configuration)
try: content = await loop.run_in_executor(None, self._read_file, filename)
content = await loop.run_in_executor(None, self._read_file, filename)
except OSError:
self.send_error(404)
return
self.write(content) self.write(content)
def _read_file(self, filename: str) -> bytes: def _read_file(self, filename: str) -> bytes:
@ -769,6 +773,7 @@ class EditRequestHandler(BaseHandler):
@authenticated @authenticated
@bind_config @bind_config
async def post(self, configuration: str | None = None): async def post(self, configuration: str | None = None):
"""Write the content of a file."""
loop = asyncio.get_running_loop() loop = asyncio.get_running_loop()
config_file = settings.rel_path(configuration) config_file = settings.rel_path(configuration)
await loop.run_in_executor( await loop.run_in_executor(