Fix /docs endpoint by setting root_path parameter in FastAPI app, by
doing so there's no need to have custom url_for fucntion
This commit is contained in:
@ -29,7 +29,11 @@ def create_app() -> FastAPI:
|
|||||||
title='Hysteria Webpanel',
|
title='Hysteria Webpanel',
|
||||||
description='Webpanel for Hysteria',
|
description='Webpanel for Hysteria',
|
||||||
version='0.1.0',
|
version='0.1.0',
|
||||||
|
contact={
|
||||||
|
'github': 'https://github.com/ReturnFI/Hysteria2'
|
||||||
|
},
|
||||||
debug=CONFIGS.DEBUG,
|
debug=CONFIGS.DEBUG,
|
||||||
|
root_path=f'/{CONFIGS.ROOT_PATH}',
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set up static files
|
# Set up static files
|
||||||
@ -44,10 +48,10 @@ def create_app() -> FastAPI:
|
|||||||
app.add_middleware(AfterRequestMiddleware)
|
app.add_middleware(AfterRequestMiddleware)
|
||||||
|
|
||||||
# Set up Routers
|
# Set up Routers
|
||||||
app.include_router(routers.basic.router, prefix='', tags=['basic']) # Add basic router
|
app.include_router(routers.basic.router, prefix='', tags=['Basic Routes[Web]']) # Add basic router
|
||||||
app.include_router(routers.login.router, prefix='', tags=['authentication']) # Add authentication router
|
app.include_router(routers.login.router, prefix='', tags=['Authentication[Web]']) # Add authentication router
|
||||||
app.include_router(routers.user.router, prefix='/users', tags=['users']) # Add user router
|
app.include_router(routers.user.router, prefix='/users', tags=['User Management[Web]']) # Add user router
|
||||||
app.include_router(routers.api.v1.api_v1_router, prefix='/api/v1', tags=['v1']) # Add API version 1 router
|
app.include_router(routers.api.v1.api_v1_router, prefix='/api/v1', tags=['API Version 1']) # Add API version 1 router
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
from .dependency import get_templates, get_session_manager, url_for
|
from .dependency import get_templates, get_session_manager
|
||||||
|
|||||||
@ -1,28 +1,24 @@
|
|||||||
from fastapi import Request
|
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
from jinja2 import pass_context
|
|
||||||
from typing import Any
|
|
||||||
from starlette.datastructures import URL
|
|
||||||
|
|
||||||
from session import SessionStorage, SessionManager
|
from session import SessionStorage, SessionManager
|
||||||
from config import CONFIGS
|
from config import CONFIGS
|
||||||
|
|
||||||
__TEMPLATES = Jinja2Templates(directory='templates')
|
__TEMPLATES = Jinja2Templates(directory='templates')
|
||||||
|
|
||||||
|
# This was a custom url_for function for Jinja2 to add a prefix to the generated URL but we fix the url generation by setting the root path
|
||||||
|
# @pass_context
|
||||||
|
# def url_for(context: dict[str, Any], name: str = '', **path_params: dict[str, Any]) -> URL:
|
||||||
|
# '''
|
||||||
|
# Custom url_for function for Jinja2 to add a prefix to the generated URL.
|
||||||
|
# '''
|
||||||
|
# request: Request = context["request"]
|
||||||
|
# url = request.url_for(name, **path_params)
|
||||||
|
# prefixed_path = f"{CONFIGS.ROOT_PATH.rstrip('/')}/{url.path.lstrip('/')}"
|
||||||
|
|
||||||
@pass_context
|
# return url.replace(path=prefixed_path)
|
||||||
def url_for(context: dict[str, Any], name: str = '', **path_params: dict[str, Any]) -> URL:
|
|
||||||
'''
|
|
||||||
Custom url_for function for Jinja2 to add a prefix to the generated URL.
|
|
||||||
'''
|
|
||||||
request: Request = context["request"]
|
|
||||||
url = request.url_for(name, **path_params)
|
|
||||||
prefixed_path = f"{CONFIGS.ROOT_PATH.rstrip('/')}/{url.path.lstrip('/')}"
|
|
||||||
|
|
||||||
return url.replace(path=prefixed_path)
|
|
||||||
|
|
||||||
|
|
||||||
__TEMPLATES.env.globals['url_for'] = url_for # type: ignore
|
# __TEMPLATES.env.globals['url_for'] = url_for # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def get_templates() -> Jinja2Templates:
|
def get_templates() -> Jinja2Templates:
|
||||||
|
|||||||
@ -5,7 +5,6 @@ from starlette.types import ASGIApp
|
|||||||
from typing import Awaitable, Callable
|
from typing import Awaitable, Callable
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
from dependency import url_for
|
|
||||||
from session import SessionManager
|
from session import SessionManager
|
||||||
|
|
||||||
|
|
||||||
@ -16,7 +15,6 @@ class AuthMiddleware(BaseHTTPMiddleware):
|
|||||||
super().__init__(app)
|
super().__init__(app)
|
||||||
self.__session_manager = session_manager
|
self.__session_manager = session_manager
|
||||||
self.__api_token = api_token
|
self.__api_token = api_token
|
||||||
self.__url_for = url_for
|
|
||||||
|
|
||||||
async def dispatch(self, request: Request, call_next: Callable[[Request], Awaitable[Response]]):
|
async def dispatch(self, request: Request, call_next: Callable[[Request], Awaitable[Response]]):
|
||||||
'''Handles session authentication.'''
|
'''Handles session authentication.'''
|
||||||
@ -43,7 +41,7 @@ class AuthMiddleware(BaseHTTPMiddleware):
|
|||||||
if not session_id:
|
if not session_id:
|
||||||
if is_api_request:
|
if is_api_request:
|
||||||
raise HTTPException(status_code=401, detail="Unauthorized")
|
raise HTTPException(status_code=401, detail="Unauthorized")
|
||||||
return RedirectResponse(url=self.__url_for(context={'request': request}, name='login'), status_code=302)
|
return RedirectResponse(url=request.url_for('login'), status_code=302)
|
||||||
|
|
||||||
session_data = self.__session_manager.get_session(session_id)
|
session_data = self.__session_manager.get_session(session_id)
|
||||||
|
|
||||||
@ -51,12 +49,12 @@ class AuthMiddleware(BaseHTTPMiddleware):
|
|||||||
if is_api_request:
|
if is_api_request:
|
||||||
raise HTTPException(status_code=401, detail="The session is invalid.")
|
raise HTTPException(status_code=401, detail="The session is invalid.")
|
||||||
|
|
||||||
return RedirectResponse(url=self.__url_for(context={'request': request}, name='login'), status_code=302)
|
return RedirectResponse(url=request.url_for('login'), status_code=302)
|
||||||
|
|
||||||
if session_data.expires_at < datetime.now(timezone.utc):
|
if session_data.expires_at < datetime.now(timezone.utc):
|
||||||
if is_api_request:
|
if is_api_request:
|
||||||
raise HTTPException(status_code=401, detail="The session has expired.")
|
raise HTTPException(status_code=401, detail="The session has expired.")
|
||||||
|
|
||||||
return RedirectResponse(url=self.__url_for(context={'request': request}, name='login'), status_code=302)
|
return RedirectResponse(url=request.url_for('login'), status_code=302)
|
||||||
|
|
||||||
return await call_next(request)
|
return await call_next(request)
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from fastapi import APIRouter, Depends, Form, Request
|
|||||||
from fastapi.responses import RedirectResponse
|
from fastapi.responses import RedirectResponse
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
|
|
||||||
from dependency import get_templates, get_session_manager, url_for
|
from dependency import get_templates, get_session_manager
|
||||||
from session import SessionManager
|
from session import SessionManager
|
||||||
from config import CONFIGS
|
from config import CONFIGS
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ async def login_post(
|
|||||||
|
|
||||||
session_id = session_manager.set_session(username)
|
session_id = session_manager.set_session(username)
|
||||||
|
|
||||||
res = RedirectResponse(url=url_for(context={'request': request}, name='index'), status_code=302)
|
res = RedirectResponse(url=request.url_for('index'), status_code=302)
|
||||||
res.set_cookie(key='session_id', value=session_id)
|
res.set_cookie(key='session_id', value=session_id)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
@ -40,6 +40,6 @@ async def logout(request: Request, session_manager: SessionManager = Depends(get
|
|||||||
if session_id:
|
if session_id:
|
||||||
session_manager.revoke_session(session_id)
|
session_manager.revoke_session(session_id)
|
||||||
|
|
||||||
res = RedirectResponse(url=url_for(context={'request': request}, name='index'), status_code=302)
|
res = RedirectResponse(url=request.url_for('index'), status_code=302)
|
||||||
res.delete_cookie('session_id')
|
res.delete_cookie('session_id')
|
||||||
return res
|
return res
|
||||||
|
|||||||
Reference in New Issue
Block a user