fix: normalize existing Syncthing route paths
This commit is contained in:
@@ -369,8 +369,8 @@ class SyncthingRouteManager:
|
||||
raise RoutePathConflict("new route path contains unrelated data")
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@staticmethod
|
||||
def _validate_folder(
|
||||
self,
|
||||
folder: dict[str, Any],
|
||||
api_path: str,
|
||||
local_device_id: str,
|
||||
@@ -382,7 +382,15 @@ class SyncthingRouteManager:
|
||||
for item in raw_devices
|
||||
if isinstance(item, dict) and isinstance(item.get("deviceID"), str)
|
||||
} if isinstance(raw_devices, list) else set()
|
||||
if folder.get("path") != api_path:
|
||||
try:
|
||||
configured_api_path = self._normalized_folder_api_path(
|
||||
folder.get("path")
|
||||
)
|
||||
except RoutePathConflict as exc:
|
||||
raise RoutePathConflict(
|
||||
"existing route ID uses a different path"
|
||||
) from exc
|
||||
if configured_api_path != api_path:
|
||||
raise RoutePathConflict("existing route ID uses a different path")
|
||||
if folder.get("type") != "sendreceive":
|
||||
raise RouteSetupError("existing route folder is not sendreceive")
|
||||
@@ -391,6 +399,27 @@ class SyncthingRouteManager:
|
||||
if folder.get("paused") is True:
|
||||
raise RouteSetupError("existing route folder is paused")
|
||||
|
||||
def _normalized_folder_api_path(self, value: Any) -> str:
|
||||
"""Normalize Syncthing's absolute and home-relative path spellings."""
|
||||
|
||||
if not isinstance(value, str) or not value:
|
||||
raise RoutePathConflict("existing route folder path is invalid")
|
||||
candidate = PurePosixPath(value)
|
||||
if candidate.parts and candidate.parts[0] == "~":
|
||||
candidate = self.config.api_root.joinpath(*candidate.parts[1:])
|
||||
if not candidate.is_absolute() or any(
|
||||
part in {"", ".", ".."} for part in candidate.parts
|
||||
):
|
||||
raise RoutePathConflict("existing route folder path is unsafe")
|
||||
normalized = candidate.as_posix()
|
||||
try:
|
||||
self.config.roots.api_to_local(normalized)
|
||||
except ConfigError as exc:
|
||||
raise RoutePathConflict(
|
||||
"existing route folder path is outside the sync root"
|
||||
) from exc
|
||||
return normalized
|
||||
|
||||
def _wait(self, deadline: float) -> None:
|
||||
if time.monotonic() >= deadline:
|
||||
raise RouteSetupTimeout("route setup timed out")
|
||||
|
||||
Reference in New Issue
Block a user