diff --git a/backend/app/core/conf.py b/backend/app/core/conf.py index 85f1c8e5..61a26ccf 100644 --- a/backend/app/core/conf.py +++ b/backend/app/core/conf.py @@ -49,6 +49,15 @@ def validator_api_url(cls, values): values['OPENAPI_URL'] = None return values + # Demo mode + # Only GET, OPTIONS requests are allowed + DEMO_MODE: bool = True + DEMO_MODE_EXCLUDE: set[tuple[str, str]] = { + ('POST', f'{API_V1_STR}/auth/login'), + ('POST', f'{API_V1_STR}/auth/logout'), + ('GET', f'{API_V1_STR}/auth/captcha'), + } + # Uvicorn UVICORN_HOST: str = '127.0.0.1' UVICORN_PORT: int = 8000 @@ -109,6 +118,7 @@ def validator_api_url(cls, values): CASBIN_EXCLUDE: set[tuple[str, str]] = { ('POST', f'{API_V1_STR}/auth/swagger_login'), ('POST', f'{API_V1_STR}/auth/login'), + ('POST', f'{API_V1_STR}/auth/logout'), ('POST', f'{API_V1_STR}/auth/register'), ('GET', f'{API_V1_STR}/auth/captcha'), } @@ -118,6 +128,7 @@ def validator_api_url(cls, values): MENU_EXCLUDE: list[str] = [ 'auth:swagger_login', 'auth:login', + 'auth:logout', 'auth:register', 'auth:captcha', ] diff --git a/backend/app/core/registrar.py b/backend/app/core/registrar.py index 2bc8fe6c..71c67e24 100644 --- a/backend/app/core/registrar.py +++ b/backend/app/core/registrar.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- from contextlib import asynccontextmanager -from fastapi import FastAPI +from fastapi import FastAPI, Depends from fastapi_limiter import FastAPILimiter from fastapi_pagination import add_pagination from starlette.middleware.authentication import AuthenticationMiddleware @@ -15,6 +15,7 @@ from backend.app.database.db_mysql import create_table from backend.app.middleware.jwt_auth_middleware import JwtAuthMiddleware from backend.app.middleware.opera_log_middleware import OperaLogMiddleware +from backend.app.utils.demo_site import demo_site from backend.app.utils.health_check import ensure_unique_route_names, http_limit_callback from backend.app.utils.openapi import simplify_operation_ids @@ -135,8 +136,10 @@ def register_router(app: FastAPI): :param app: FastAPI :return: """ + dependencies = [Depends(demo_site)] if settings.DEMO_MODE else None + # API - app.include_router(v1) + app.include_router(v1, dependencies=dependencies) # Extra ensure_unique_route_names(app) diff --git a/backend/app/utils/demo_site.py b/backend/app/utils/demo_site.py new file mode 100644 index 00000000..648a7936 --- /dev/null +++ b/backend/app/utils/demo_site.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +from fastapi import Request + +from backend.app.common.exception import errors +from backend.app.core.conf import settings + + +async def demo_site(request: Request): + """演示站点""" + + method = request.method + path = request.url.path + if ( + settings.DEMO_MODE + and method != 'GET' + and method != 'OPTIONS' + and (method, path) not in settings.DEMO_MODE_EXCLUDE + ): + raise errors.ForbiddenError(msg='演示环境下禁止执行此操作')