From 9562b07a0f754802b8dbf5a069dd1eb765d21527 Mon Sep 17 00:00:00 2001 From: pollutri Date: Mon, 26 Jan 2026 13:09:01 +0100 Subject: [PATCH] Poxy the request from the GUI to the CORE --- .env | 2 ++ app.py | 55 +++++++++++++++++++++++++++++++++------------- config_env.py | 4 ++++ requirements.txt | 3 ++- routes/reslevis.py | 3 +-- 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/.env b/.env index 9933a8d..8b3f27c 100644 --- a/.env +++ b/.env @@ -19,3 +19,5 @@ KEYCLOAK_JWKS_URL=${KEYCLOAK_PROTOCOL_ENDPOINT}/certs KEYCLOAK_AUTH_URL=${KEYCLOAK_PROTOCOL_ENDPOINT}/auth KEYCLOAK_TOKEN_URL=${KEYCLOAK_PROTOCOL_ENDPOINT}/token +#CORE info +CORE_API_URL=http://localhost:1902 diff --git a/app.py b/app.py index 37d32e6..0849f9f 100644 --- a/app.py +++ b/app.py @@ -35,17 +35,14 @@ from starlette.middleware.cors import CORSMiddleware from starlette.responses import FileResponse from starlette.types import ASGIApp, Message, Receive, Scope, Send - from models.cellular_hardware import cellularHardware from models.cellular_hardwares import cellularHardwares from models.call import call, post_call from models.calls import calls from models.httpresponse import httpResponse400, httpResponse200, httpResponse500 - from fastapi_login import LoginManager - from core.security import manager, NotAuthenticatedException from routes import auth as _auth @@ -66,11 +63,6 @@ reslevis_router = _reslevis.router from fastapi import FastAPI, Security from fastapi.security import OAuth2AuthorizationCodeBearer -#AUTH_URL = "https://10.251.0.30:10002/realms/API.Server.local/protocol/openid-connect/auth" -#AUTH_URL = "https://192.168.1.3:10002/realms/API.Server.local/protocol/openid-connect/auth" -#TOKEN_URL = "https://10.251.0.30:10002/realms/API.Server.local/protocol/openid-connect/token" -#TOKEN_URL = "https://192.168.1.3:10002/realms/API.Server.local/protocol/openid-connect/token" - AUTH_URL = config_env.KEYCLOAK_AUTH_URL TOKEN_URL = config_env.KEYCLOAK_TOKEN_URL @@ -99,6 +91,33 @@ logging.basicConfig( format="%(levelname)s:%(name)s:%(message)s" ) +#ResLevis CORE Proxying +CORE_BASE_URL = config_env.CORE_API_URL.rstrip("/") + +HOP_BY_HOP = { + "connection", "keep-alive", "proxy-authenticate", "proxy-authorization", + "te", "trailers", "transfer-encoding", "upgrade", +} + +def _filter_headers(headers: dict) -> dict: + return {k: v for k, v in headers.items() if k.lower() not in HOP_BY_HOP} + +async def _forward_to_core(request: Request, body: bytes) -> Response: + url = f"{CORE_BASE_URL}{request.url.path}" + async with httpx.AsyncClient(timeout=30.0) as client: + resp = await client.request( + request.method, + url, + params=request.query_params, + content=body, + headers=_filter_headers(dict(request.headers)), + ) + return Response( + content=resp.content, + status_code=resp.status_code, + headers=_filter_headers(dict(resp.headers)), + media_type=resp.headers.get("content-type"), + ) ALLOWED_HOSTS = ["*"] @@ -110,6 +129,17 @@ app.add_middleware( allow_headers=["*"], ) +#ResLevis CORE middleware +@app.middleware("http") +async def local_then_core(request: Request, call_next): + # only proxy CRUD for Reslevis (change prefix or methods if needed) + if request.url.path.startswith("/reslevis/") and request.method in {"POST", "PUT", "DELETE", "PATCH"}: + body = await request.body() # raw body preserved + local_resp = await call_next(request) # local storage runs here + if local_resp.status_code >= 400: + return local_resp # stop if local failed + return await _forward_to_core(request, body) + return await call_next(request) @app.exception_handler(NotAuthenticatedException) def auth_exception_handler(request: Request, exc: NotAuthenticatedException): @@ -126,6 +156,7 @@ app.include_router(majornet_router) app.include_router(contacts_router) app.include_router(reslevis_router, prefix="/reslevis", tags=["Reslevis"]) + @app.get("/") async def root(): #return {"url": "/docs"} @@ -145,8 +176,6 @@ async def get_documentation(): return get_swagger_ui_html(openapi_url="/openapi.json", title="docs") - - @app.post("/majortel/call/", tags=["Majortel"]) async def route_call(active_user=Depends(manager),callerNumber=None, calledNumber=None): try: @@ -360,8 +389,4 @@ async def majortel_calls_id_delete(call_id,active_user=Depends(manager)): elif (response == "Not found"): return JSONResponse(status_code=404, content={"message": "Call not found"}) else: - return JSONResponse(status_code=500, content={"message": "Server error"}) - - - - + return JSONResponse(status_code=500, content={"message": "Server error"}) \ No newline at end of file diff --git a/config_env.py b/config_env.py index 3699f09..c9c0500 100644 --- a/config_env.py +++ b/config_env.py @@ -4,6 +4,7 @@ from dotenv import load_dotenv load_dotenv() +#Keycloak configuration (look in the .env) SECRET = os.getenv("SECRET") KEYCLOAK_AUDIENCE = os.getenv("KEYCLOAK_AUDIENCE") KEYCLOAK_SERVER = os.getenv("KEYCLOAK_SERVER") @@ -13,3 +14,6 @@ KEYCLOAK_JWKS_URL = os.getenv("KEYCLOAK_JWKS_URL") KEYCLOAK_AUTH_URL = os.getenv("KEYCLOAK_AUTH_URL") KEYCLOAK_TOKEN_URL = os.getenv("KEYCLOAK_TOKEN_URL") +#API PROXYING TO THE CORE +CORE_API_URL = os.getenv("CORE_API_URL", "http://localhost:1902") + diff --git a/requirements.txt b/requirements.txt index a80747b..2ea0aed 100644 --- a/requirements.txt +++ b/requirements.txt @@ -36,4 +36,5 @@ urllib3==1.22 uvicorn==0.9.0 uvloop==0.13.0 vobject==0.9.6.1 -websockets==8.0.2 \ No newline at end of file +websockets==8.0.2 +httpx diff --git a/routes/reslevis.py b/routes/reslevis.py index d45b37c..43b2e0a 100644 --- a/routes/reslevis.py +++ b/routes/reslevis.py @@ -289,5 +289,4 @@ def updateSubject(item: SubjectItem): @router.delete("/removeSubject/{subject_id}", tags=["Reslevis"], dependencies=[Depends(get_current_user)]) def removeSubject(subject_id: str): subject_repo.remove(subject_id) - return {"message": "OK"} - + return {"message": "OK"} \ No newline at end of file