Skip to content

Commit 6c74522

Browse files
committed
make restore system originated agnostic
1 parent cb5dea9 commit 6c74522

1 file changed

Lines changed: 38 additions & 62 deletions

File tree

backend/app.py

Lines changed: 38 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,14 +1412,12 @@ def _verify_restore_paths_writable(db_path: Path, data_dir: Path) -> tuple[bool,
14121412
def _detect_old_data_dir(db_path: Path) -> str | None:
14131413
"""
14141414
Infer the data_dir used by a backup DB by inspecting org_dir values.
1415-
Returns the old data directory as a string (may contain backslashes for Windows paths),
1416-
or None if there are no organizations.
1415+
Returns the old data directory as a string, or None if there are no organizations.
14171416
"""
14181417
try:
14191418
conn = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True)
14201419
try:
1421-
cursor = conn.execute("SELECT org_dir FROM organizations LIMIT 10")
1422-
rows = [row[0] for row in cursor.fetchall()]
1420+
rows = [row[0] for row in conn.execute("SELECT org_dir FROM organizations LIMIT 10")]
14231421
finally:
14241422
conn.close()
14251423
except Exception as e:
@@ -1429,91 +1427,69 @@ def _detect_old_data_dir(db_path: Path) -> str | None:
14291427
if not rows:
14301428
return None
14311429

1432-
# Determine path separator (\ for Windows, / for Unix)
1433-
first_path = rows[0]
1434-
sep = "\\" if "\\" in first_path else "/"
1430+
sep = "\\" if "\\" in rows[0] else "/"
1431+
parents = {path[:path.rfind(sep)] for path in rows if path.rfind(sep) > 0}
14351432

1436-
# Extract parent directory by finding the last separator
1437-
def get_parent(path: str) -> str:
1438-
idx = path.rfind(sep)
1439-
return path[:idx] if idx > 0 else ""
1440-
1441-
parents = {get_parent(r) for r in rows}
14421433
if len(parents) != 1:
1443-
logger.warning(f"Inconsistent org_dir parents in backup DB; skipping path rewrite")
1434+
logger.warning("Inconsistent org_dir parents in backup DB; skipping path rewrite")
14441435
return None
14451436

14461437
return parents.pop()
14471438

14481439

14491440
def _rewrite_paths_in_db(db_path: Path, old_data_dir: str, new_data_dir: Path) -> int:
14501441
"""
1451-
Replace old_data_dir prefix with new_data_dir in all path-bearing columns.
1452-
Handles both Windows and Unix paths correctly.
1453-
Returns the number of rows updated.
1442+
Replace old_data_dir prefix with new_data_dir in path-bearing columns.
1443+
Handles both Windows and Unix paths. Returns the number of rows updated.
14541444
"""
1455-
old_prefix = old_data_dir
14561445
new_prefix = str(new_data_dir)
1446+
sep = "\\" if "\\" in old_data_dir else "/"
14571447
updated = 0
14581448

1449+
def rewrite_absolute(path: str) -> str | None:
1450+
"""Rewrite absolute path if it starts with old prefix, else return None."""
1451+
if not path.startswith(old_data_dir):
1452+
return None
1453+
rel = path[len(old_data_dir):].lstrip(sep).replace("\\", "/")
1454+
return f"{new_prefix}/{rel}" if rel else new_prefix
1455+
14591456
try:
14601457
conn = sqlite3.connect(str(db_path))
14611458
try:
1462-
# Detect separator in old path (Windows uses \, Unix uses /)
1463-
sep = "\\" if "\\" in old_prefix else "/"
1464-
1465-
# Rewrite organizations.org_dir
1466-
cursor = conn.execute("SELECT id, org_dir FROM organizations")
1467-
for org_id, org_dir in cursor.fetchall():
1468-
if org_dir.startswith(old_prefix):
1469-
# Extract relative part after old prefix and separator
1470-
rel_part = org_dir[len(old_prefix):]
1471-
if rel_part.startswith(sep):
1472-
rel_part = rel_part[1:]
1473-
# Reconstruct with new prefix using forward slashes
1474-
new_org_dir = f"{new_prefix}/{rel_part}" if rel_part else new_prefix
1475-
conn.execute(
1476-
"UPDATE organizations SET org_dir = ? WHERE id = ?",
1477-
(new_org_dir, org_id)
1478-
)
1459+
# Rewrite organizations.org_dir (absolute paths)
1460+
for org_id, org_dir in conn.execute("SELECT id, org_dir FROM organizations"):
1461+
new_path = rewrite_absolute(org_dir)
1462+
if new_path:
1463+
conn.execute("UPDATE organizations SET org_dir = ? WHERE id = ?", (new_path, org_id))
14791464
updated += 1
14801465

1481-
# Rewrite crls.crl_path if it contains absolute paths
1482-
cursor = conn.execute("SELECT id, crl_path FROM crls")
1483-
for crl_id, crl_path in cursor.fetchall():
1484-
if crl_path.startswith(old_prefix):
1485-
rel_part = crl_path[len(old_prefix):]
1486-
if rel_part.startswith(sep):
1487-
rel_part = rel_part[1:]
1488-
new_crl_path = f"{new_prefix}/{rel_part}" if rel_part else new_prefix
1489-
conn.execute(
1490-
"UPDATE crls SET crl_path = ? WHERE id = ?",
1491-
(new_crl_path, crl_id)
1492-
)
1466+
# Rewrite crls.crl_path (absolute or relative)
1467+
for crl_id, crl_path in conn.execute("SELECT id, crl_path FROM crls"):
1468+
new_path = rewrite_absolute(crl_path)
1469+
if new_path:
1470+
conn.execute("UPDATE crls SET crl_path = ? WHERE id = ?", (new_path, crl_id))
1471+
updated += 1
1472+
elif sep == "\\" and "\\" in crl_path:
1473+
new_path = crl_path.replace("\\", "/")
1474+
conn.execute("UPDATE crls SET crl_path = ? WHERE id = ?", (new_path, crl_id))
14931475
updated += 1
14941476

1495-
# Rewrite relative paths in certificates table (convert \ to / if crossing platforms)
1496-
if sep == "\\": # Windows paths being restored elsewhere
1497-
cursor = conn.execute(
1477+
# Rewrite certificate paths (relative paths with backslashes)
1478+
if sep == "\\":
1479+
for cert_id, cert_path, key_path, csr_path, pwd_path in conn.execute(
14981480
"SELECT id, cert_path, key_path, csr_path, pwd_path FROM certificates"
1499-
)
1500-
for cert_id, cert_path, key_path, csr_path, pwd_path in cursor.fetchall():
1481+
):
15011482
updates = {}
1502-
if cert_path and "\\" in cert_path:
1503-
updates["cert_path"] = cert_path.replace("\\", "/")
1504-
if key_path and "\\" in key_path:
1505-
updates["key_path"] = key_path.replace("\\", "/")
1506-
if csr_path and "\\" in csr_path:
1507-
updates["csr_path"] = csr_path.replace("\\", "/")
1508-
if pwd_path and "\\" in pwd_path:
1509-
updates["pwd_path"] = pwd_path.replace("\\", "/")
1483+
for col, val in [("cert_path", cert_path), ("key_path", key_path),
1484+
("csr_path", csr_path), ("pwd_path", pwd_path)]:
1485+
if val and "\\" in val:
1486+
updates[col] = val.replace("\\", "/")
15101487

15111488
if updates:
15121489
set_clause = ", ".join(f"{col} = ?" for col in updates.keys())
1513-
values = list(updates.values()) + [cert_id]
15141490
conn.execute(
15151491
f"UPDATE certificates SET {set_clause} WHERE id = ?",
1516-
values
1492+
list(updates.values()) + [cert_id]
15171493
)
15181494
updated += len(updates)
15191495

0 commit comments

Comments
 (0)