|
@@ -1,6 +1,6 @@
|
|
-from fastapi import FastAPI, Form, Request, Depends, HTTPException, Body
|
|
|
|
|
|
+from fastapi import FastAPI, Form, Request, HTTPException
|
|
from pydantic import BaseModel
|
|
from pydantic import BaseModel
|
|
-from fastapi.responses import JSONResponse, RedirectResponse, HTMLResponse
|
|
|
|
|
|
+from fastapi.responses import JSONResponse, RedirectResponse
|
|
from fastapi.templating import Jinja2Templates
|
|
from fastapi.templating import Jinja2Templates
|
|
from fastapi.staticfiles import StaticFiles
|
|
from fastapi.staticfiles import StaticFiles
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
@@ -8,12 +8,12 @@ from starlette.middleware.sessions import SessionMiddleware
|
|
import secrets
|
|
import secrets
|
|
import uvicorn
|
|
import uvicorn
|
|
import logging
|
|
import logging
|
|
-import requests # Import the requests library here
|
|
|
|
-from typing import Annotated, Dict, List, Optional #import typing
|
|
|
|
|
|
+import requests
|
|
|
|
+from typing import Dict, Optional
|
|
|
|
|
|
|
|
|
|
# --- Keycloak Configuration ---
|
|
# --- Keycloak Configuration ---
|
|
-KEYCLOAK_SERVER_URL = "http://165.22.75.145:8080" # Double-check this! Changed to http
|
|
|
|
|
|
+KEYCLOAK_SERVER_URL = "http://165.22.75.145:8080"
|
|
KEYCLOAK_REALM = "Generation"
|
|
KEYCLOAK_REALM = "Generation"
|
|
KEYCLOAK_CLIENT_ID = "web-app-pw"
|
|
KEYCLOAK_CLIENT_ID = "web-app-pw"
|
|
KEYCLOAK_CLIENT_SECRET = "fQGWt8HSPn65cCKTOzE5FigqZhf8QTYW"
|
|
KEYCLOAK_CLIENT_SECRET = "fQGWt8HSPn65cCKTOzE5FigqZhf8QTYW"
|
|
@@ -26,12 +26,6 @@ app = FastAPI()
|
|
logging.basicConfig(level=logging.INFO)
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
-# --- CORS ---
|
|
|
|
-# origins = [
|
|
|
|
-# "http://localhost:8000/*",
|
|
|
|
-# "http://localhost:3000/*",
|
|
|
|
-# ]
|
|
|
|
-
|
|
|
|
app.add_middleware(
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
CORSMiddleware,
|
|
allow_origins=["*"],
|
|
allow_origins=["*"],
|
|
@@ -54,7 +48,7 @@ def get_token_from_keycloak(username, password) -> Dict:
|
|
}
|
|
}
|
|
try:
|
|
try:
|
|
response = requests.post(url, headers=headers, data=payload, timeout=10)
|
|
response = requests.post(url, headers=headers, data=payload, timeout=10)
|
|
- response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
|
|
|
|
|
|
+ response.raise_for_status()
|
|
return response.json()
|
|
return response.json()
|
|
except requests.exceptions.RequestException as e:
|
|
except requests.exceptions.RequestException as e:
|
|
logger.error(f"Error getting token from Keycloak: {e}")
|
|
logger.error(f"Error getting token from Keycloak: {e}")
|
|
@@ -120,17 +114,171 @@ def logout_keycloak(refresh_token:str):
|
|
logger.error(f"Error logging out user: {e}")
|
|
logger.error(f"Error logging out user: {e}")
|
|
raise HTTPException(status_code=500, detail=f"Failed to logout user: {e}") from e
|
|
raise HTTPException(status_code=500, detail=f"Failed to logout user: {e}") from e
|
|
|
|
|
|
-class Credenziali(BaseModel):
|
|
|
|
- username: str
|
|
|
|
- password: str
|
|
|
|
|
|
|
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
|
templates = Jinja2Templates(directory="templates")
|
|
templates = Jinja2Templates(directory="templates")
|
|
|
|
|
|
|
|
+@app.get("/mappa_login")
|
|
|
|
+async def mappa_login(request: Request):
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return templates.TemplateResponse("mappa_login.html", {"request": request})
|
|
|
|
+
|
|
|
|
+@app.get("/tfo")
|
|
|
|
+async def tfo(request: Request):
|
|
|
|
+ if "access_token" in request.session.keys():
|
|
|
|
+ if introspect_keycloak_token_request(str(request.session.get("access_token")))["active"] == True:
|
|
|
|
+ return templates.TemplateResponse("TFO.html", {"request": request})
|
|
|
|
+ try:
|
|
|
|
+ tokens = refresh_token_from_keycloak(str(request.session.get("refresh_token")))
|
|
|
|
+
|
|
|
|
+ request.session.update({"access_token" : tokens["access_token"], "refresh_token" : tokens["refresh_token"]})
|
|
|
|
+ user_info = get_user_info_from_keycloak(tokens["access_token"])
|
|
|
|
+
|
|
|
|
+ request.session.update(
|
|
|
|
+ {"ruolo": user_info["ruolo"], "codice_fiscale": user_info["CF"]}
|
|
|
|
+ )
|
|
|
|
+ return RedirectResponse(url=f"/tfo?ruolo={user_info["ruolo"]}&codice_fiscale={user_info["CF"]}", status_code=303)
|
|
|
|
+
|
|
|
|
+ except Exception as e:
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
+
|
|
|
|
+@app.get("/instructions")
|
|
|
|
+async def instructions(request: Request):
|
|
|
|
+ if "access_token" in request.session.keys():
|
|
|
|
+ if introspect_keycloak_token_request(str(request.session.get("access_token")))["active"] == True:
|
|
|
|
+ return templates.TemplateResponse("instructions.html", {"request": request})
|
|
|
|
+ try:
|
|
|
|
+ tokens = refresh_token_from_keycloak(str(request.session.get("refresh_token")))
|
|
|
|
+
|
|
|
|
+ request.session.update({"access_token" : tokens["access_token"], "refresh_token" : tokens["refresh_token"]})
|
|
|
|
+ user_info = get_user_info_from_keycloak(tokens["access_token"])
|
|
|
|
+
|
|
|
|
+ request.session.update(
|
|
|
|
+ {"ruolo": user_info["ruolo"], "codice_fiscale": user_info["CF"]}
|
|
|
|
+ )
|
|
|
|
+ return RedirectResponse(url=f"/instructions?ruolo={user_info["ruolo"]}&codice_fiscale={user_info["CF"]}", status_code=303)
|
|
|
|
+
|
|
|
|
+ except Exception as e:
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
+
|
|
|
|
+@app.get("/buildings")
|
|
|
|
+async def buildings(request: Request):
|
|
|
|
+ if "access_token" in request.session.keys():
|
|
|
|
+ if introspect_keycloak_token_request(str(request.session.get("access_token")))["active"] == True:
|
|
|
|
+ return templates.TemplateResponse("buildings.html", {"request": request})
|
|
|
|
+ try:
|
|
|
|
+ tokens = refresh_token_from_keycloak(str(request.session.get("refresh_token")))
|
|
|
|
+
|
|
|
|
+ request.session.update({"access_token" : tokens["access_token"], "refresh_token" : tokens["refresh_token"]})
|
|
|
|
+ user_info = get_user_info_from_keycloak(tokens["access_token"])
|
|
|
|
+
|
|
|
|
+ request.session.update(
|
|
|
|
+ {"ruolo": user_info["ruolo"], "codice_fiscale": user_info["CF"]}
|
|
|
|
+ )
|
|
|
|
+ return RedirectResponse(url=f"/buildings?ruolo={user_info["ruolo"]}&codice_fiscale={user_info["CF"]}", status_code=303)
|
|
|
|
+
|
|
|
|
+ except Exception as e:
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
+
|
|
|
|
+@app.get("/faq")
|
|
|
|
+async def faq(request: Request):
|
|
|
|
+ if "access_token" in request.session.keys():
|
|
|
|
+ if introspect_keycloak_token_request(str(request.session.get("access_token")))["active"] == True:
|
|
|
|
+ return templates.TemplateResponse("faq.html", {"request": request})
|
|
|
|
+ try:
|
|
|
|
+ tokens = refresh_token_from_keycloak(str(request.session.get("refresh_token")))
|
|
|
|
+
|
|
|
|
+ request.session.update({"access_token" : tokens["access_token"], "refresh_token" : tokens["refresh_token"]})
|
|
|
|
+ user_info = get_user_info_from_keycloak(tokens["access_token"])
|
|
|
|
+
|
|
|
|
+ request.session.update(
|
|
|
|
+ {"ruolo": user_info["ruolo"], "codice_fiscale": user_info["CF"]}
|
|
|
|
+ )
|
|
|
|
+ return RedirectResponse(url=f"/faq?ruolo={user_info["ruolo"]}&codice_fiscale={user_info["CF"]}", status_code=303)
|
|
|
|
+
|
|
|
|
+ except Exception as e:
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
+
|
|
|
|
+@app.get("/techsup")
|
|
|
|
+async def techsup(request: Request):
|
|
|
|
+ if "access_token" in request.session.keys():
|
|
|
|
+ if introspect_keycloak_token_request(str(request.session.get("access_token")))["active"] == True:
|
|
|
|
+ return templates.TemplateResponse("techsup.html", {"request": request})
|
|
|
|
+ try:
|
|
|
|
+ tokens = refresh_token_from_keycloak(str(request.session.get("refresh_token")))
|
|
|
|
+
|
|
|
|
+ request.session.update({"access_token" : tokens["access_token"], "refresh_token" : tokens["refresh_token"]})
|
|
|
|
+ user_info = get_user_info_from_keycloak(tokens["access_token"])
|
|
|
|
+
|
|
|
|
+ request.session.update(
|
|
|
|
+ {"ruolo": user_info["ruolo"], "codice_fiscale": user_info["CF"]}
|
|
|
|
+ )
|
|
|
|
+ return RedirectResponse(url=f"/techsup?ruolo={user_info["ruolo"]}&codice_fiscale={user_info["CF"]}", status_code=303)
|
|
|
|
+
|
|
|
|
+ except Exception as e:
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
|
|
@app.get("/callback")
|
|
@app.get("/callback")
|
|
async def callback(request: Request):
|
|
async def callback(request: Request):
|
|
- return templates.TemplateResponse("mappa_logout.html", context={"request": request, "title": "Mappa"})
|
|
|
|
|
|
+ if "access_token" in request.session.keys():
|
|
|
|
+ if introspect_keycloak_token_request(str(request.session.get("access_token")))["active"] == True:
|
|
|
|
+ return templates.TemplateResponse("mappa_logout.html", {"request": request})
|
|
|
|
+ try:
|
|
|
|
+ tokens = refresh_token_from_keycloak(str(request.session.get("refresh_token")))
|
|
|
|
+
|
|
|
|
+ request.session.update({"access_token" : tokens["access_token"], "refresh_token" : tokens["refresh_token"]})
|
|
|
|
+ user_info = get_user_info_from_keycloak(tokens["access_token"])
|
|
|
|
+
|
|
|
|
+ request.session.update(
|
|
|
|
+ {"ruolo": user_info["ruolo"], "codice_fiscale": user_info["CF"]}
|
|
|
|
+ )
|
|
|
|
+ return RedirectResponse(url=f"/callback?ruolo={user_info["ruolo"]}&codice_fiscale={user_info["CF"]}", status_code=303)
|
|
|
|
+
|
|
|
|
+ except Exception as e:
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
+
|
|
|
|
+@app.get("/admin")
|
|
|
|
+async def admin(request: Request):
|
|
|
|
+ if "access_token" in request.session.keys():
|
|
|
|
+ if introspect_keycloak_token_request(str(request.session.get("access_token")))["active"] == True:
|
|
|
|
+ if get_user_info_from_keycloak(str(request.session.get("access_token")))["ruolo"] == "amministratore":
|
|
|
|
+ return templates.TemplateResponse("ADMIN.html", {"request": request})
|
|
|
|
+ return RedirectResponse(url="/callback", status_code=303)
|
|
|
|
+ try:
|
|
|
|
+ tokens = refresh_token_from_keycloak(str(request.session.get("refresh_token")))
|
|
|
|
+
|
|
|
|
+ request.session.update({"access_token" : tokens["access_token"], "refresh_token" : tokens["refresh_token"]})
|
|
|
|
+ user_info = get_user_info_from_keycloak(tokens["access_token"])
|
|
|
|
+
|
|
|
|
+ request.session.update(
|
|
|
|
+ {"ruolo": user_info["ruolo"], "codice_fiscale": user_info["CF"]}
|
|
|
|
+ )
|
|
|
|
+ return RedirectResponse(url=f"/admin?ruolo={user_info["ruolo"]}&codice_fiscale={user_info["CF"]}", status_code=303)
|
|
|
|
+
|
|
|
|
+ except Exception as e:
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return RedirectResponse(url="/access", status_code=303)
|
|
|
|
+
|
|
|
|
|
|
@app.get("/access")
|
|
@app.get("/access")
|
|
@app.post("/access")
|
|
@app.post("/access")
|
|
@@ -138,27 +286,21 @@ async def login(request: Request, username: Optional[str] = Form(None), password
|
|
error = None
|
|
error = None
|
|
if request.method == "POST":
|
|
if request.method == "POST":
|
|
try:
|
|
try:
|
|
- request.session["user_info"] = {}
|
|
|
|
- #print(request.session.get("tokens"))
|
|
|
|
-
|
|
|
|
- tokens = get_token_from_keycloak(username, password)#request.body.json()["username"], request.json()["password"])
|
|
|
|
-
|
|
|
|
- # Save tokens and information to the session
|
|
|
|
-
|
|
|
|
- request.session["access_token"] = tokens["access_token"]
|
|
|
|
- request.session["refresh_token"] = tokens["refresh_token"]
|
|
|
|
|
|
+ request.session.clear()
|
|
|
|
|
|
- #print(tokens["access_token"])
|
|
|
|
|
|
+ tokens = get_token_from_keycloak(username, password)
|
|
|
|
|
|
- # Get user info and save it to the session too
|
|
|
|
|
|
+ request.session.update(
|
|
|
|
+ {"access_token": tokens["access_token"], "refresh_token": tokens["refresh_token"]}
|
|
|
|
+ )
|
|
|
|
|
|
user_info = get_user_info_from_keycloak(tokens["access_token"])
|
|
user_info = get_user_info_from_keycloak(tokens["access_token"])
|
|
|
|
|
|
- request.session["user_info"] = user_info
|
|
|
|
|
|
+ request.session.update(
|
|
|
|
+ {"ruolo": user_info["ruolo"], "codice_fiscale": user_info["CF"]}
|
|
|
|
+ )
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- return RedirectResponse(url=f"/callback?access_token={tokens["access_token"]}&refresh_token={tokens["refresh_token"]}", status_code=303)
|
|
|
|
|
|
+ return RedirectResponse(url=f"/callback?ruolo={user_info["ruolo"]}&codice_fiscale={user_info["CF"]}", status_code=303)
|
|
|
|
|
|
except HTTPException as e:
|
|
except HTTPException as e:
|
|
|
|
|
|
@@ -170,24 +312,108 @@ async def login(request: Request, username: Optional[str] = Form(None), password
|
|
|
|
|
|
return JSONResponse(content={"detail": "An unexpected error occurred"}, status_code=500)
|
|
return JSONResponse(content={"detail": "An unexpected error occurred"}, status_code=500)
|
|
|
|
|
|
- if request.session.get("access_token") is not None:
|
|
|
|
- #print(request.session.get("access_token"))
|
|
|
|
- if introspect_keycloak_token_request(str(request.session.get("access_token")))["active"] == True:
|
|
|
|
- #print(3)
|
|
|
|
- return RedirectResponse(url="/callback", status_code=303)
|
|
|
|
- try:
|
|
|
|
- tokens = refresh_token_from_keycloak(str(request.session.get("refresh_token")))
|
|
|
|
|
|
+ if "access_token" in request.session.keys():
|
|
|
|
+ if introspect_keycloak_token_request(str(request.session.get("access_token")))["active"] == True:
|
|
|
|
+ return RedirectResponse(url="/callback", status_code=303)
|
|
|
|
+ try:
|
|
|
|
+ tokens = refresh_token_from_keycloak(str(request.session.get("refresh_token")))
|
|
|
|
+
|
|
|
|
+ request.session.update({"access_token" : tokens["access_token"], "refresh_token" : tokens["refresh_token"]})
|
|
|
|
+ user_info = get_user_info_from_keycloak(tokens["access_token"])
|
|
|
|
+
|
|
|
|
+ request.session.update(
|
|
|
|
+ {"ruolo": user_info["ruolo"], "codice_fiscale": user_info["CF"]}
|
|
|
|
+ )
|
|
|
|
+ return RedirectResponse(url=f"/callback?ruolo={user_info["ruolo"]}&codice_fiscale={user_info["CF"]}", status_code=303)
|
|
|
|
|
|
- #localStorage.setItem('jwtToken', tuoJWT);
|
|
|
|
- request.session["access_token"] = tokens["access_token"]
|
|
|
|
- request.session["refresh_token"] = tokens["refresh_token"]
|
|
|
|
|
|
+ except Exception as e:
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return templates.TemplateResponse("login.html", {"request": request, "error": error})
|
|
|
|
+
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return templates.TemplateResponse("login.html", {"request": request, "error": error})
|
|
|
|
|
|
- return RedirectResponse(url=f"/callback?access_token={tokens["access_token"]}&refresh_token={tokens["refresh_token"]}", status_code=303)
|
|
|
|
|
|
+@app.get("/refresh")
|
|
|
|
+async def refresh(request: Request):
|
|
|
|
+ """Refreshes the access token using the refresh token in the session."""
|
|
|
|
+ refresh_token = request.session.get("refresh_token")
|
|
|
|
+ if not refresh_token:
|
|
|
|
+ raise HTTPException(status_code=401, detail="Refresh token not found in session")
|
|
|
|
+
|
|
|
|
+ try:
|
|
|
|
+ new_tokens = refresh_token_from_keycloak(refresh_token)
|
|
|
|
+ request.session["access_token"] = new_tokens["access_token"]
|
|
|
|
+ request.session["refresh_token"] = new_tokens["refresh_token"]
|
|
|
|
+ new_user_info = get_user_info_from_keycloak(new_tokens["access_token"])
|
|
|
|
+ request.session["user_info"] = new_user_info
|
|
|
|
+ return {"message": "Token refreshed successfully", "access_token": new_tokens["access_token"], "user_info": new_user_info}
|
|
|
|
+ except HTTPException as e:
|
|
|
|
+ return JSONResponse(content={"detail": e.detail}, status_code=e.status_code)
|
|
|
|
+ except Exception as e:
|
|
|
|
+ logger.error(f"An unexpected error occurred during token refresh: {e}")
|
|
|
|
+ return JSONResponse(content={"detail": "An unexpected error occurred"}, status_code=500)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+@app.get("/introspect")
|
|
|
|
+async def introspect(request: Request):
|
|
|
|
+ """Introspects the access token in the session."""
|
|
|
|
+ access_token = request.session.get("access_token")
|
|
|
|
+ if not access_token:
|
|
|
|
+ raise HTTPException(status_code=401, detail="Access token not found in session")
|
|
|
|
+
|
|
|
|
+ try:
|
|
|
|
+ introspect_data = introspect_keycloak_token_request(access_token)
|
|
|
|
+ return {"message": "Token introspection successful", "introspect_data": introspect_data}
|
|
|
|
+ except HTTPException as e:
|
|
|
|
+ return JSONResponse(content={"detail": e.detail}, status_code=e.status_code)
|
|
|
|
+ except Exception as e:
|
|
|
|
+ logger.error(f"An unexpected error occurred during token introspection: {e}")
|
|
|
|
+ return JSONResponse(content={"detail": "An unexpected error occurred"}, status_code=500)
|
|
|
|
+
|
|
|
|
+@app.get("/userinfo")
|
|
|
|
+async def user_info(request: Request):
|
|
|
|
+ """Retrieves and returns user information stored in the session."""
|
|
|
|
+ user_info = request.session.get("user_info")
|
|
|
|
+ if not user_info:
|
|
|
|
+ raise HTTPException(status_code=401, detail="User info not found in session")
|
|
|
|
+ return {"message": "User information retrieved", "user_info": user_info}
|
|
|
|
+
|
|
|
|
+@app.get("/logout_keycloak")
|
|
|
|
+async def logout_user(request: Request):
|
|
|
|
+ """Logs out a user by revoking the refresh token."""
|
|
|
|
+ refresh_token = request.session.get("refresh_token")
|
|
|
|
+ if not refresh_token:
|
|
|
|
+ raise HTTPException(status_code=401, detail="Refresh token not found in session")
|
|
|
|
+ try:
|
|
|
|
+ logout_keycloak(refresh_token)
|
|
|
|
+ request.session.clear()
|
|
|
|
+ return {"message": "Logout successful"}
|
|
|
|
+ except HTTPException as e:
|
|
|
|
+ return JSONResponse(content={"detail": e.detail}, status_code=e.status_code)
|
|
|
|
+ except Exception as e:
|
|
|
|
+ logger.error(f"An unexpected error occurred during logout: {e}")
|
|
|
|
+ return JSONResponse(content={"detail": "An unexpected error occurred"}, status_code=500)
|
|
|
|
+
|
|
|
|
+@app.get("/protected")
|
|
|
|
+async def protected_endpoint(request: Request):
|
|
|
|
+ """A protected endpoint that requires a valid access token."""
|
|
|
|
+ access_token = request.session.get("access_token")
|
|
|
|
+ if not access_token:
|
|
|
|
+ raise HTTPException(status_code=401, detail="Access token not found in session")
|
|
|
|
+ try:
|
|
|
|
+ introspect_data = introspect_keycloak_token_request(access_token)
|
|
|
|
+ if not introspect_data.get("active"):
|
|
|
|
+ raise HTTPException(status_code=401, detail="Access token is not active")
|
|
|
|
+ return JSONResponse({"message": f"Hello, world! (Protected)", "introspect": introspect_data})
|
|
|
|
+ except HTTPException as e:
|
|
|
|
+ return JSONResponse(content={"detail": e.detail}, status_code=e.status_code)
|
|
|
|
+ except Exception as e:
|
|
|
|
+ logger.error(f"An unexpected error occurred during token introspection: {e}")
|
|
|
|
+ return JSONResponse(content={"detail": "An unexpected error occurred"}, status_code=500)
|
|
|
|
+
|
|
|
|
|
|
- except Exception as e:
|
|
|
|
|
|
+# --- Run the App ---
|
|
|
|
+if __name__ == "__main__":
|
|
|
|
+ uvicorn.run(app, host="localhost", port=8000)
|
|
|
|
|
|
- logger.error(f"An unexpected error occurred during login: {e}")
|
|
|
|
|
|
|
|
- return JSONResponse(content={"detail": "An unexpected error occurred"}, status_code=500)
|
|
|
|
-
|
|
|
|
- return templates.TemplateResponse("login.html", {"request": request, "error": error})
|
|
|