feat(05-10): oauth_initiate returns 200 JSON {url} instead of 302 redirect

- Remove response_class=RedirectResponse from @router.get decorator
- Replace both RedirectResponse(status_code=302) returns with JSONResponse({url})
- Frontend can now inject Bearer header before navigating to OAuth URL (T-05-10-01)
- Update test_connect_google_drive to expect 200 JSON (regression fix)
This commit is contained in:
curo1305
2026-05-30 11:24:33 +02:00
parent 9b6d3f91d4
commit e2e499b8b1
2 changed files with 31 additions and 13 deletions
+11 -5
View File
@@ -311,22 +311,28 @@ async def _upsert_cloud_connection(
# ── GET /api/cloud/oauth/initiate/{provider} ──────────────────────────────────
@router.get("/oauth/initiate/{provider}", response_class=RedirectResponse)
@router.get("/oauth/initiate/{provider}")
async def oauth_initiate(
provider: str,
request: Request,
current_user: User = Depends(get_regular_user),
):
) -> dict:
"""Start the OAuth flow for Google Drive or OneDrive.
Generates a CSRF state token, stores it in Redis with TTL 1800 (30 min),
and redirects the browser to the provider's authorization URL.
and returns the provider's authorization URL as JSON so the frontend can
navigate using fetch() with the Bearer header (plan 05-10 fix).
Returns: {"url": "<authorization_url>"}
Security:
- state token is secrets.token_urlsafe(32) — 256 bits of entropy (T-05-05-01)
- Redis key is single-use: deleted in the callback handler (T-05-05-02)
- Only google_drive and onedrive are accepted (T-05-05-06)
- Endpoint requires get_regular_user — no unauthenticated access (T-05-10-01)
"""
from fastapi.responses import JSONResponse # already available via fastapi
if provider not in VALID_OAUTH_PROVIDERS:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
@@ -359,7 +365,7 @@ async def oauth_initiate(
prompt="consent",
state=state_token,
)
return RedirectResponse(url=authorization_url, status_code=302)
return JSONResponse({"url": authorization_url})
elif provider == "onedrive":
import msal # lazy import
@@ -375,7 +381,7 @@ async def oauth_initiate(
redirect_uri=redirect_uri,
state=state_token,
)
return RedirectResponse(url=auth_url, status_code=302)
return JSONResponse({"url": auth_url})
# ── GET /api/cloud/oauth/callback/{provider} ──────────────────────────────────