|
|
from fastapi import APIRouter, Request, HTTPException |
|
|
from authlib.integrations.starlette_client import OAuth |
|
|
from app.core.config import settings |
|
|
|
|
|
router = APIRouter() |
|
|
|
|
|
|
|
|
oauth = OAuth() |
|
|
|
|
|
|
|
|
|
|
|
CONF_URL = f"https://login.microsoftonline.com/{settings.MS_TENANT_ID}/v2.0/.well-known/openid-configuration" |
|
|
|
|
|
oauth.register( |
|
|
name='microsoft', |
|
|
client_id=settings.MS_CLIENT_ID, |
|
|
client_secret=settings.MS_CLIENT_SECRET, |
|
|
server_metadata_url=CONF_URL, |
|
|
client_kwargs={ |
|
|
'scope': 'openid email profile User.Read' |
|
|
} |
|
|
) |
|
|
|
|
|
@router.get("/login") |
|
|
async def login(request: Request): |
|
|
""" |
|
|
Redirects the user to the Microsoft Login page. |
|
|
""" |
|
|
redirect_uri = settings.MS_REDIRECT_URI |
|
|
return await oauth.microsoft.authorize_redirect(request, redirect_uri) |
|
|
|
|
|
|
|
|
@router.get("/callback") |
|
|
async def auth_callback(request: Request): |
|
|
""" |
|
|
Handles the callback from Microsoft after successful login. |
|
|
Exchanges the authorization code for an access token and user info. |
|
|
""" |
|
|
try: |
|
|
token = await oauth.microsoft.authorize_access_token(request) |
|
|
user = token.get('userinfo') |
|
|
|
|
|
if not user: |
|
|
|
|
|
|
|
|
user = await oauth.microsoft.userinfo(token=token) |
|
|
|
|
|
|
|
|
|
|
|
request.session['user'] = dict(user) |
|
|
|
|
|
return {"message": "Login successful", "user": user} |
|
|
except Exception as e: |
|
|
|
|
|
raise HTTPException(status_code=400, detail=f"SSO Login Failed: {str(e)}") |
|
|
|
|
|
|
|
|
@router.get("/logout") |
|
|
async def logout(request: Request): |
|
|
""" |
|
|
Clears the local session. |
|
|
""" |
|
|
request.session.pop('user', None) |
|
|
return {"message": "Logged out successfully"} |