fix 401
This commit is contained in:
parent
0d9d7af779
commit
faaf50694f
58
api/src/core/public_paths.py
Normal file
58
api/src/core/public_paths.py
Normal file
@ -0,0 +1,58 @@
|
||||
"""Публичные пути для AuthorizationMiddleware: SPA и infra, без /api."""
|
||||
|
||||
ABSOLUTE_PUBLIC_PATHS = (
|
||||
"",
|
||||
"/",
|
||||
"/healthcheck",
|
||||
"/healthcheck2",
|
||||
"/healthz",
|
||||
"/readyz",
|
||||
)
|
||||
|
||||
START_PUBLIC_PREFIXES = (
|
||||
"/static",
|
||||
"/back-static",
|
||||
"/openapi.json",
|
||||
"/docs",
|
||||
"/docs-local",
|
||||
"/login",
|
||||
"/task",
|
||||
"/project",
|
||||
"/forms",
|
||||
"/table",
|
||||
"/admin_panel",
|
||||
"/dicts",
|
||||
"/svod",
|
||||
"/index",
|
||||
"/favicon",
|
||||
"/assets",
|
||||
"/images",
|
||||
)
|
||||
|
||||
|
||||
def with_root(path: str, root_path: str) -> tuple[str, ...]:
|
||||
if not root_path:
|
||||
return (path,)
|
||||
root = root_path.rstrip("/")
|
||||
if path == "":
|
||||
return (path, root)
|
||||
return (path, f"{root}{path}")
|
||||
|
||||
|
||||
def public_endpoint_specs(root_path: str = "") -> list[tuple[str, str]]:
|
||||
"""Пары (mode, path): mode is 'absolute' or 'start'."""
|
||||
specs: list[tuple[str, str]] = []
|
||||
seen: set[tuple[str, str]] = set()
|
||||
for path in ABSOLUTE_PUBLIC_PATHS:
|
||||
for full in with_root(path, root_path):
|
||||
item = ("absolute", full)
|
||||
if item not in seen:
|
||||
seen.add(item)
|
||||
specs.append(item)
|
||||
for path in START_PUBLIC_PREFIXES:
|
||||
for full in with_root(path, root_path):
|
||||
item = ("start", full)
|
||||
if item not in seen:
|
||||
seen.add(item)
|
||||
specs.append(item)
|
||||
return specs
|
||||
@ -18,6 +18,7 @@ from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware
|
||||
from src.api.v1.router import api_router
|
||||
from src.core.config import settings
|
||||
from src.core.exception_handlers import register_exception_handlers
|
||||
from src.core.public_paths import public_endpoint_specs
|
||||
from src.db.base import engine
|
||||
from src.db.session import create_tables
|
||||
|
||||
@ -186,58 +187,12 @@ async def readyz(response: Response):
|
||||
|
||||
|
||||
if not settings.DEBUG:
|
||||
_search = {"absolute": SearchType.ABSOLUTE, "start": SearchType.START}
|
||||
app.add_middleware(
|
||||
AuthorizationMiddleware,
|
||||
open_endpoints=[
|
||||
OpenEndpoint(path="", type_search=SearchType.ABSOLUTE),
|
||||
OpenEndpoint(path=settings.ROOT_PATH + "", type_search=SearchType.ABSOLUTE),
|
||||
OpenEndpoint(path="/", type_search=SearchType.ABSOLUTE),
|
||||
OpenEndpoint(path=settings.ROOT_PATH + "/", type_search=SearchType.ABSOLUTE),
|
||||
OpenEndpoint(path="/healthcheck", type_search=SearchType.ABSOLUTE),
|
||||
OpenEndpoint(
|
||||
path=settings.ROOT_PATH + "/healthcheck",
|
||||
type_search=SearchType.ABSOLUTE,
|
||||
),
|
||||
OpenEndpoint(path="/healthcheck2", type_search=SearchType.ABSOLUTE),
|
||||
OpenEndpoint(
|
||||
path=settings.ROOT_PATH + "/healthcheck2",
|
||||
type_search=SearchType.ABSOLUTE,
|
||||
),
|
||||
OpenEndpoint(path="/healthz", type_search=SearchType.ABSOLUTE),
|
||||
OpenEndpoint(
|
||||
path=settings.ROOT_PATH + "/healthz",
|
||||
type_search=SearchType.ABSOLUTE,
|
||||
),
|
||||
OpenEndpoint(path="/readyz", type_search=SearchType.ABSOLUTE),
|
||||
OpenEndpoint(
|
||||
path=settings.ROOT_PATH + "/readyz",
|
||||
type_search=SearchType.ABSOLUTE,
|
||||
),
|
||||
OpenEndpoint(path="/static", type_search=SearchType.START),
|
||||
OpenEndpoint(
|
||||
path=settings.ROOT_PATH + "/static",
|
||||
type_search=SearchType.START,
|
||||
),
|
||||
OpenEndpoint(path="/back-static", type_search=SearchType.START),
|
||||
OpenEndpoint(
|
||||
path=settings.ROOT_PATH + "/back-static",
|
||||
type_search=SearchType.START,
|
||||
),
|
||||
OpenEndpoint(path="/openapi.json", type_search=SearchType.START),
|
||||
OpenEndpoint(
|
||||
path=settings.ROOT_PATH + "/openapi.json",
|
||||
type_search=SearchType.START,
|
||||
),
|
||||
OpenEndpoint(path="/docs", type_search=SearchType.START),
|
||||
OpenEndpoint(
|
||||
path=settings.ROOT_PATH + "/docs",
|
||||
type_search=SearchType.START,
|
||||
),
|
||||
OpenEndpoint(path="/docs-local", type_search=SearchType.START),
|
||||
OpenEndpoint(
|
||||
path=settings.ROOT_PATH + "/docs-local",
|
||||
type_search=SearchType.START,
|
||||
),
|
||||
OpenEndpoint(path=path, type_search=_search[mode])
|
||||
for mode, path in public_endpoint_specs(settings.ROOT_PATH)
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
20
api/tests/unit/test_public_paths.py
Normal file
20
api/tests/unit/test_public_paths.py
Normal file
@ -0,0 +1,20 @@
|
||||
from src.core.public_paths import public_endpoint_specs
|
||||
|
||||
|
||||
def test_login_page_is_public_without_root():
|
||||
specs = public_endpoint_specs("")
|
||||
assert ("start", "/login") in specs
|
||||
assert ("absolute", "/") in specs
|
||||
|
||||
|
||||
def test_login_page_is_public_with_root_path():
|
||||
specs = public_endpoint_specs("/aurora/apps/fastapi-tsygankov-test")
|
||||
assert ("start", "/login") in specs
|
||||
assert ("start", "/aurora/apps/fastapi-tsygankov-test/login") in specs
|
||||
|
||||
|
||||
def test_api_routes_are_not_public():
|
||||
specs = public_endpoint_specs("/aurora/apps/fastapi-tsygankov-test")
|
||||
paths = [path for _, path in specs]
|
||||
assert not any(path == "/api" or path.startswith("/api/") for path in paths)
|
||||
assert not any("/api/v1" in path for path in paths)
|
||||
Loading…
x
Reference in New Issue
Block a user