feat: explorador de archivos local y autenticacion/conexion a unidad de red UNC en storage root

This commit is contained in:
Carlos Tello
2026-08-17 00:05:15 -03:00
parent 7badc34816
commit f3b6d8ef71
5 changed files with 457 additions and 25 deletions
+110
View File
@@ -1,5 +1,12 @@
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Optional
import os
import string
import uuid
from pathlib import Path
from pydantic import BaseModel
from app.core.database import get_db
from app.api.deps import require_admin
from app.models.models import User
@@ -8,6 +15,11 @@ from app.services.settings_service import get_all_settings, update_settings_serv
router = APIRouter(prefix="/settings", tags=["System Settings"])
class TestShareRequest(BaseModel):
path: str
username: str
password: str
@router.get("", response_model=SystemSettingsResponse)
async def get_settings(
db: AsyncSession = Depends(get_db),
@@ -22,6 +34,13 @@ async def get_settings(
"default_keep_daily": int(settings_dict.get("default_keep_daily", 7)),
"default_keep_weekly": int(settings_dict.get("default_keep_weekly", 4)),
"default_keep_monthly": int(settings_dict.get("default_keep_monthly", 12)),
"auth_mode": settings_dict.get("auth_mode", "local"),
"radius_host": settings_dict.get("radius_host", ""),
"radius_port": int(settings_dict.get("radius_port", 1812)) if settings_dict.get("radius_port") else 1812,
"radius_secret": settings_dict.get("radius_secret", ""),
"storage_network_enabled": settings_dict.get("storage_network_enabled", "false").lower() == "true",
"storage_network_user": settings_dict.get("storage_network_user", ""),
"storage_network_pass": settings_dict.get("storage_network_pass", ""),
}
@router.put("", response_model=SystemSettingsResponse)
@@ -49,4 +68,95 @@ async def update_settings(
"default_keep_daily": int(settings_dict.get("default_keep_daily", 7)),
"default_keep_weekly": int(settings_dict.get("default_keep_weekly", 4)),
"default_keep_monthly": int(settings_dict.get("default_keep_monthly", 12)),
"auth_mode": settings_dict.get("auth_mode", "local"),
"radius_host": settings_dict.get("radius_host", ""),
"radius_port": int(settings_dict.get("radius_port", 1812)) if settings_dict.get("radius_port") else 1812,
"radius_secret": settings_dict.get("radius_secret", ""),
"storage_network_enabled": settings_dict.get("storage_network_enabled", "false").lower() == "true",
"storage_network_user": settings_dict.get("storage_network_user", ""),
"storage_network_pass": settings_dict.get("storage_network_pass", ""),
}
@router.get("/explore-dir")
async def explore_directory(
path: Optional[str] = None,
admin_user: User = Depends(require_admin)
):
"""
Explore directories on the host filesystem.
"""
import platform
if not path or path.strip() == "":
if platform.system().lower() == "windows":
drives = []
for letter in string.ascii_uppercase:
drive_path = f"{letter}:\\"
if os.path.exists(drive_path):
drives.append({"name": drive_path, "path": drive_path})
return {"current_path": "", "folders": drives}
else:
return {"current_path": "/", "folders": [{"name": "/", "path": "/"}]}
# Resolve path
target = Path(path).resolve()
if not target.exists() or not target.is_dir():
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"The path '{path}' does not exist or is not a directory."
)
try:
folders = []
for entry in os.scandir(target):
try:
if entry.is_dir():
folders.append({
"name": entry.name,
"path": str(Path(entry.path).resolve())
})
except Exception:
continue # Skip inaccessible
folders.sort(key=lambda x: x["name"].lower())
return {
"current_path": str(target),
"parent_path": str(target.parent) if target.parent != target else None,
"folders": folders
}
except Exception as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Failed to read directory contents: {str(e)}"
)
@router.post("/test-network-share")
async def test_network_share(
payload: TestShareRequest,
admin_user: User = Depends(require_admin)
):
"""
Attempts to connect to a UNC network share and tests write access.
"""
from app.services.settings_service import connect_network_share
ok = connect_network_share(payload.path, payload.username, payload.password)
if not ok:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Failed to connect to the network share. Check the server path, username, and password."
)
try:
target_path = Path(payload.path)
os.makedirs(target_path, exist_ok=True)
test_file = target_path / f".write_test_{uuid.uuid4().hex[:6]}"
test_file.touch()
test_file.unlink()
return {"message": "Network share connected and write access verified successfully!"}
except Exception as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Network share connected, but write access test failed: {str(e)}"
)