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 os
from pathlib import Path
from typing import Any
from esphome.core import CORE
from esphome.helpers import get_bool_env
@ -69,7 +69,8 @@ class DashboardSettings:
# Compare password in constant running time (to prevent timing attacks)
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)
# Raises ValueError if not relative to ESPHome config folder
Path(joined_path).resolve().relative_to(self.absolute_config_dir)

View File

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