mirror of
https://github.com/zvx-echo6/central.git
synced 2026-05-21 18:14:44 +02:00
fix(gui): use fastapi-csrf-protect native body-token validation
The library supports form-data tokens via token_location="body" and token_key config options, which we missed in the initial integration. Removed hand-rolled _validate_csrf_form helper in favor of the library's validate_csrf method. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
c529708c75
commit
17dd653bd8
2 changed files with 6 additions and 17 deletions
|
|
@ -37,6 +37,8 @@ def _configure_csrf() -> None:
|
||||||
|
|
||||||
class CsrfSettings(BaseModel):
|
class CsrfSettings(BaseModel):
|
||||||
secret_key: str
|
secret_key: str
|
||||||
|
token_location: str = "body"
|
||||||
|
token_key: str = "csrf_token"
|
||||||
|
|
||||||
@CsrfProtect.load_config
|
@CsrfProtect.load_config
|
||||||
def get_csrf_config():
|
def get_csrf_config():
|
||||||
|
|
|
||||||
|
|
@ -24,19 +24,6 @@ from central.gui.db import get_pool
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
async def _validate_csrf_form(request, csrf_protect):
|
|
||||||
"""Validate CSRF token from form data."""
|
|
||||||
form = await request.form()
|
|
||||||
csrf_token = form.get("csrf_token")
|
|
||||||
if csrf_token:
|
|
||||||
cookie_token = request.cookies.get("fastapi-csrf-token")
|
|
||||||
if not cookie_token or cookie_token != csrf_token:
|
|
||||||
from fastapi_csrf_protect.exceptions import TokenValidationError
|
|
||||||
raise TokenValidationError("CSRF token mismatch")
|
|
||||||
else:
|
|
||||||
from fastapi_csrf_protect.exceptions import MissingTokenError
|
|
||||||
raise MissingTokenError("Missing CSRF token in form")
|
|
||||||
|
|
||||||
def _get_templates():
|
def _get_templates():
|
||||||
"""Get templates instance (deferred import to avoid circular)."""
|
"""Get templates instance (deferred import to avoid circular)."""
|
||||||
from central.gui import templates
|
from central.gui import templates
|
||||||
|
|
@ -119,7 +106,7 @@ async def setup_submit(
|
||||||
pool = get_pool()
|
pool = get_pool()
|
||||||
|
|
||||||
# Validate CSRF
|
# Validate CSRF
|
||||||
await _validate_csrf_form(request, csrf_protect)
|
await csrf_protect.validate_csrf(request)
|
||||||
|
|
||||||
# Validate input
|
# Validate input
|
||||||
error = None
|
error = None
|
||||||
|
|
@ -213,7 +200,7 @@ async def login_submit(
|
||||||
pool = get_pool()
|
pool = get_pool()
|
||||||
|
|
||||||
# Validate CSRF
|
# Validate CSRF
|
||||||
await _validate_csrf_form(request, csrf_protect)
|
await csrf_protect.validate_csrf(request)
|
||||||
|
|
||||||
# Look up operator
|
# Look up operator
|
||||||
async with pool.acquire() as conn:
|
async with pool.acquire() as conn:
|
||||||
|
|
@ -279,7 +266,7 @@ async def logout(
|
||||||
pool = get_pool()
|
pool = get_pool()
|
||||||
|
|
||||||
# Validate CSRF
|
# Validate CSRF
|
||||||
await _validate_csrf_form(request, csrf_protect)
|
await csrf_protect.validate_csrf(request)
|
||||||
|
|
||||||
# Get current session
|
# Get current session
|
||||||
session_token = request.cookies.get("central_session")
|
session_token = request.cookies.get("central_session")
|
||||||
|
|
@ -328,7 +315,7 @@ async def change_password_submit(
|
||||||
operator = request.state.operator
|
operator = request.state.operator
|
||||||
|
|
||||||
# Validate CSRF
|
# Validate CSRF
|
||||||
await _validate_csrf_form(request, csrf_protect)
|
await csrf_protect.validate_csrf(request)
|
||||||
|
|
||||||
# Get current password hash
|
# Get current password hash
|
||||||
async with pool.acquire() as conn:
|
async with pool.acquire() as conn:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue