feat(auth): add Microsoft OAuth callback
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -104,3 +104,20 @@ async def google_callback(
|
|||||||
refresh_token=create_refresh_token({"sub": str(user.id)}),
|
refresh_token=create_refresh_token({"sub": str(user.id)}),
|
||||||
is_new_user=is_new,
|
is_new_user=is_new,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/microsoft/callback", response_model=OAuthCallbackResponse)
|
||||||
|
async def microsoft_callback(
|
||||||
|
payload: OAuthCallbackPayload,
|
||||||
|
db: Annotated[AsyncSession, Depends(get_admin_db)],
|
||||||
|
) -> OAuthCallbackResponse:
|
||||||
|
if not settings.MS_CLIENT_ID:
|
||||||
|
raise HTTPException(status_code=503, detail="Microsoft sign-in not configured")
|
||||||
|
redirect_uri = f"{settings.OAUTH_REDIRECT_BASE}/auth/microsoft/callback"
|
||||||
|
profile = await microsoft_exchange_code(payload.code, redirect_uri)
|
||||||
|
user, is_new = await _sign_in_or_register(db, "microsoft", profile)
|
||||||
|
return OAuthCallbackResponse(
|
||||||
|
access_token=create_access_token({"sub": str(user.id)}),
|
||||||
|
refresh_token=create_refresh_token({"sub": str(user.id)}),
|
||||||
|
is_new_user=is_new,
|
||||||
|
)
|
||||||
|
|||||||
@@ -93,3 +93,28 @@ async def test_google_callback_503_when_unconfigured(client, monkeypatch):
|
|||||||
"/api/v1/auth/google/callback", json={"code": "x"}
|
"/api/v1/auth/google/callback", json={"code": "x"}
|
||||||
)
|
)
|
||||||
assert response.status_code == 503
|
assert response.status_code == 503
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_microsoft_callback_creates_user(client, test_db, monkeypatch):
|
||||||
|
from app.core.config import settings
|
||||||
|
monkeypatch.setattr(settings, "MS_CLIENT_ID", "client_dummy")
|
||||||
|
monkeypatch.setattr(settings, "MS_CLIENT_SECRET", "secret_dummy")
|
||||||
|
|
||||||
|
profile = OAuthProfile(
|
||||||
|
provider_subject="ms_subject_789",
|
||||||
|
email="msuser@example.com",
|
||||||
|
name="MS User",
|
||||||
|
)
|
||||||
|
with patch("app.api.endpoints.oauth.microsoft_exchange_code", return_value=profile):
|
||||||
|
response = await client.post(
|
||||||
|
"/api/v1/auth/microsoft/callback", json={"code": "auth_code"}
|
||||||
|
)
|
||||||
|
assert response.status_code == 200, response.json()
|
||||||
|
user = (await test_db.execute(
|
||||||
|
select(User).where(User.email == "msuser@example.com")
|
||||||
|
)).scalar_one()
|
||||||
|
identity = (await test_db.execute(
|
||||||
|
select(OAuthIdentity).where(OAuthIdentity.user_id == user.id)
|
||||||
|
)).scalar_one()
|
||||||
|
assert identity.provider == "microsoft"
|
||||||
|
|||||||
Reference in New Issue
Block a user