]> git.giorgioravera.it Git - network-manager.git/commitdiff
Added middleware for login management
authorGiorgio Ravera <giorgio.ravera@gmail.com>
Tue, 6 Jan 2026 14:09:04 +0000 (15:09 +0100)
committerGiorgio Ravera <giorgio.ravera@gmail.com>
Tue, 6 Jan 2026 14:09:04 +0000 (15:09 +0100)
backend/main.py
backend/routes/hosts.py
backend/routes/login.py
backend/security.py

index 4f9f5f8b363954303b5bacd461d83f8336866ba5..d7c4652633db54258e19b6e701742f9199cfaa75 100644 (file)
@@ -1,20 +1,12 @@
 # backend/main.py
 
 # import standard modules
-from fastapi import FastAPI
-from fastapi import Request, Response
+from fastapi import FastAPI, Request, Response
 from fastapi.middleware.cors import CORSMiddleware
-from fastapi.responses import FileResponse, RedirectResponse
+from fastapi.responses import FileResponse, RedirectResponse, JSONResponse
 import os
 # Import local modules
-from backend.security import is_logged_in, require_login, html_protected
-from backend.db.hosts import (
-    get_hosts,
-    get_host,
-    add_host,
-    update_host,
-    delete_host
-)
+from backend.security import is_logged_in
 from backend.routes.health import router as health_router
 from backend.routes.login import router as login_router
 from backend.routes.hosts import router as hosts_router
@@ -39,19 +31,49 @@ app.add_middleware(
 )
 
 # ---------------------------------------------------------
-# FRONTEND PATHS (absolute paths inside Docker)
+# Middleware to manage Login
 # ---------------------------------------------------------
 
-# Protect html pages
-def html_protected(request: Request, filename: str):
+@app.middleware("http")
+async def session_middleware(request: Request, call_next):
+    path = request.url.path
+
+    # Excludes the login methods
+    if path.startswith("/login") or path.startswith("/api/login"):
+        return await call_next(request)
+
+    # Excludes static files
+    if (
+        path.startswith("/css") or
+        path.startswith("/js") or
+        path.endswith(".js") or
+        path.endswith(".css") or
+        path.endswith(".png") or
+        path.endswith(".jpg") or
+        path.endswith(".ico")
+    ):
+        return await call_next(request)
+
+    # Protected APIs
+    if path.startswith("/api"):
+        if not is_logged_in(request):
+            return JSONResponse({"error": "Not authenticated"}, status_code=401)
+        return await call_next(request)
+
+    # Protected HTML pages
     if not is_logged_in(request):
         return RedirectResponse("/login")
-    return FileResponse(os.path.join(FRONTEND_DIR, filename))
+
+    return await call_next(request)
+
+# ---------------------------------------------------------
+# FRONTEND PATHS (absolute paths inside Docker)
+# ---------------------------------------------------------
 
 # Homepage
 @app.get("/")
 def home(request: Request):
-    return html_protected(request, "hosts.html")
+    return FileResponse(os.path.join(FRONTEND_DIR, "hosts.html"))
 
 # Serve app.js
 @app.get("/app.js")
index 0376d2d0c2584153abff16bf0e7040d221594fa3..ecbebf65bab998f52ad3a7ed606d17b1e61b910f 100644 (file)
@@ -6,7 +6,6 @@ from fastapi.responses import FileResponse, RedirectResponse
 import os
 import ipaddress
 # Import local modules
-from backend.security import is_logged_in, require_login, html_protected
 from backend.db.hosts import (
     get_hosts,
     get_host,
@@ -27,7 +26,7 @@ router = APIRouter()
 # Hosts page
 @router.get("/hosts")
 def hosts(request: Request):
-    return html_protected(request, "hosts.html")
+    return FileResponse(os.path.join(FRONTEND_DIR, "hosts.html"))
 
 # Serve hosts.css
 @router.get("/css/hosts.css")
@@ -40,12 +39,10 @@ def css_hosts():
 
 @router.get("/api/hosts")
 def api_get_hosts(request: Request):
-    require_login(request)
     return get_hosts()
 
 @router.post("/api/hosts")
 def api_add_host(request: Request, data: dict):
-    require_login(request)
     name = data.get("name", "").strip()
     ipv4 = data.get("ipv4")
     ipv6 = data.get("ipv6")
@@ -65,12 +62,10 @@ def api_add_host(request: Request, data: dict):
 
 @router.get("/api/hosts/{host_id}")
 def api_get_host(request: Request, host_id: int):
-    require_login(request)
     return get_host(host_id) or {}
 
 @router.put("/api/hosts/{host_id}")
 def api_update_host(request: Request, data: dict, host_id: int):
-    require_login(request)
     name = data.get("name", "").strip()
     ipv4 = data.get("ipv4")
     ipv6 = data.get("ipv6")
@@ -91,6 +86,5 @@ def api_update_host(request: Request, data: dict, host_id: int):
 
 @router.delete("/api/hosts/{host_id}")
 def api_delete_host(request: Request, host_id: int):
-    require_login(request)
     delete_host(host_id)
     return {"status": "ok"}
index 88b358c1852e5c8eee07121631833855cf42c7c5..adfb98ffbbc3a571aa2613fe61ccbaa2a9f354dc 100644 (file)
@@ -6,7 +6,7 @@ from fastapi.responses import FileResponse, RedirectResponse
 import os
 import time
 # Import local modules
-from backend.security import is_logged_in, signer
+from backend.security import signer
 from backend.db.users import verify_login
 # Import config variables
 from backend.config import FRONTEND_DIR, LOGIN_MAX_ATTEMPTS, LOGIN_WINDOW_SECONDS
@@ -37,8 +37,6 @@ def check_rate_limit(ip: str):
 # Login page
 @router.get("/login")
 def login_page(request: Request):
-    if is_logged_in(request):
-        return RedirectResponse("/")
     return FileResponse(os.path.join(FRONTEND_DIR, "login.html"))
 
 # Serve login.css
index b31f092a6ceb15648a5518c55d58bb099234b428..a79148fb617c62260c901366920970c614f22162 100644 (file)
@@ -3,7 +3,6 @@
 # import standard modules
 import os
 from fastapi import Request, HTTPException
-from fastapi.responses import FileResponse, RedirectResponse
 from itsdangerous import TimestampSigner
 # Import config variables
 from backend.config import FRONTEND_DIR, SECRET_KEY
@@ -11,7 +10,7 @@ from backend.config import FRONTEND_DIR, SECRET_KEY
 signer = TimestampSigner(SECRET_KEY)
 
 # -----------------------------
-# login check
+# check session cookie
 # -----------------------------
 def is_logged_in(request: Request) -> bool:
     token = request.cookies.get("session")
@@ -24,16 +23,8 @@ def is_logged_in(request: Request) -> bool:
         return False
 
 # -----------------------------
-# login check (for api)
+# check login
 # -----------------------------
 def require_login(request: Request):
     if not is_logged_in(request):
         raise HTTPException(status_code=401, detail="Not authenticated")
-
-# -----------------------------
-# login check (for html)
-# -----------------------------
-def html_protected(request: Request, filename: str):
-    if not is_logged_in(request):
-        return RedirectResponse("/login")
-    return FileResponse(os.path.join(FRONTEND_DIR, filename))
\ No newline at end of file