# auth/msal_login.py
from __future__ import annotations
from fastapi import HTTPException, Response, status
from jose import JWTError, jwt
from .config import router
from .models import MsalPayload, Token
from .tokens import _issue_session
from .users import _provision_msal_user
[docs]
@router.post("/msal", response_model=Token)
async def msal_login(payload: MsalPayload, response: Response) -> Token:
"""
The frontend calls this route **after MSAL acquires an ID-token**.
• We *trust* any token MSAL gives us for local dev - no signature check.
Add proper validation later (see suggestions below).
• We decode the token, map claims → username/full_name,
provision a local user if necessary,
then hand out a normal taranta_jwt + cookie.
"""
try:
claims = jwt.decode(
payload.id_token,
key="", # ⇢ skip signature check for dev
algorithms=["RS256", "HS256", "RS512"],
options={
"verify_signature": False,
"verify_aud": False,
"verify_exp": False,
"verify_iss": False,
},
)
except JWTError:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Invalid ID token supplied",
)
username = (
claims.get("preferred_username")
or claims.get("email")
or claims.get("upn")
or claims.get("sub")
)
if not username:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="ID token missing usable username claim",
)
full_name = claims.get("name", "")
usr = _provision_msal_user(username, full_name)
return _issue_session(response, usr)