fix: specific redirect codes for mobile
This commit is contained in:
1 parent
7ae137f865
commit
640bbea802
1 file changed
+25
-11
+25
-11
@@ -7,7 +7,7 @@ from fastapi import FastAPI, Header, HTTPException, Request, status
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import FileResponse, RedirectResponse
|
||||
from pydantic import BaseModel
|
||||
from typing import Annotated
|
||||
from typing import Annotated, Optional
|
||||
from . import myice
|
||||
|
||||
# OIDC Configuration
|
||||
@@ -151,11 +151,10 @@ async def favico():
|
||||
|
||||
|
||||
@app.get("/login")
|
||||
async def login(request: Request):
|
||||
async def login(request: Request, redirect_uri: Optional[str] = None):
|
||||
"""Redirect to Infomaniak OIDC login"""
|
||||
import urllib.parse
|
||||
|
||||
import secrets
|
||||
import urllib.parse
|
||||
|
||||
state = secrets.token_urlsafe(32)
|
||||
nonce = secrets.token_urlsafe(32)
|
||||
@@ -196,6 +195,16 @@ async def login(request: Request):
|
||||
samesite="Lax",
|
||||
max_age=300,
|
||||
)
|
||||
# Store target redirect URI (e.g. myice://callback) for mobile app flow
|
||||
if redirect_uri:
|
||||
response.set_cookie(
|
||||
"oidc_target_redirect",
|
||||
redirect_uri,
|
||||
httponly=True,
|
||||
secure=True,
|
||||
samesite="Lax",
|
||||
max_age=300,
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@@ -204,12 +213,17 @@ async def callback(request: Request, code: str, state: str):
|
||||
"""Handle OIDC callback and exchange code for token"""
|
||||
expected_state = request.cookies.get("oidc_state")
|
||||
code_verifier = request.cookies.get("oidc_verifier")
|
||||
# Determine final redirect target (mobile app or web frontend)
|
||||
target_redirect = request.cookies.get("oidc_target_redirect") or os.environ.get(
|
||||
"FRONTEND_URL", "/"
|
||||
)
|
||||
# We should also delete state/nonce cookies once read
|
||||
if not expected_state or state != expected_state:
|
||||
response = RedirectResponse("/?error=Invalid state parameter")
|
||||
response = RedirectResponse(f"/{target_redirect}?error=Invalid state parameter")
|
||||
response.delete_cookie("oidc_state")
|
||||
response.delete_cookie("oidc_nonce")
|
||||
response.delete_cookie("oidc_verifier")
|
||||
response.delete_cookie("oidc_target_redirect")
|
||||
return response
|
||||
# Exchange authorization code for access token
|
||||
token_data = {
|
||||
@@ -227,14 +241,14 @@ async def callback(request: Request, code: str, state: str):
|
||||
# Log the error for debugging
|
||||
logging.error("Token exchange failed: %s", token_response)
|
||||
# Redirect back to frontend with error
|
||||
frontend_url = os.environ.get("FRONTEND_URL", "/")
|
||||
error_detail = token_response.get(
|
||||
"error_description", "Failed to obtain access token"
|
||||
)
|
||||
error_response = RedirectResponse(f"{frontend_url}?error={error_detail}")
|
||||
error_response = RedirectResponse(f"{target_redirect}?error={error_detail}")
|
||||
error_response.delete_cookie("oidc_state")
|
||||
error_response.delete_cookie("oidc_nonce")
|
||||
error_response.delete_cookie("oidc_verifier")
|
||||
error_response.delete_cookie("oidc_target_redirect")
|
||||
return error_response
|
||||
|
||||
access_token = token_response["access_token"]
|
||||
@@ -250,19 +264,19 @@ async def callback(request: Request, code: str, state: str):
|
||||
user_email = userinfo.get("email")
|
||||
if ALLOWED_USERS and user_email not in ALLOWED_USERS:
|
||||
# Redirect back to frontend with error
|
||||
frontend_url = os.environ.get("FRONTEND_URL", "/")
|
||||
response = RedirectResponse(f"{frontend_url}?error=User not authorized")
|
||||
response = RedirectResponse(f"{target_redirect}?error=User not authorized")
|
||||
response.delete_cookie("oidc_state")
|
||||
response.delete_cookie("oidc_nonce")
|
||||
response.delete_cookie("oidc_verifier")
|
||||
response.delete_cookie("oidc_target_redirect")
|
||||
return response
|
||||
|
||||
# Redirect back to frontend with access token and user info
|
||||
frontend_url = os.environ.get("FRONTEND_URL", "/")
|
||||
response = RedirectResponse(f"{frontend_url}#access_token={access_token}")
|
||||
response = RedirectResponse(f"{target_redirect}#access_token={access_token}")
|
||||
response.delete_cookie("oidc_state")
|
||||
response.delete_cookie("oidc_nonce")
|
||||
response.delete_cookie("oidc_verifier")
|
||||
response.delete_cookie("oidc_target_redirect")
|
||||
return response
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user