brief-extractor/backend/server/api/auth.py
2026-03-06 18:42:46 +00:00

136 lines
No EOL
3.8 KiB
Python
Executable file

"""
Authentication API endpoints
"""
import logging
from quart import Blueprint, jsonify, request
from ..auth.msal_auth import msal_auth
from ..auth.middleware import dev_mode_bypass, get_current_user
logger = logging.getLogger(__name__)
auth_bp = Blueprint('auth', __name__, url_prefix='/api/auth')
@auth_bp.route('/config', methods=['GET'])
async def get_auth_config():
"""
Get authentication configuration for frontend
Returns client configuration needed for MSAL setup
"""
try:
config = msal_auth.get_client_config()
return jsonify({
'config': config,
'devMode': msal_auth.is_dev_mode()
})
except Exception as e:
logger.error(f"Failed to get auth config: {e}")
return jsonify({
'error': 'configuration_error',
'message': 'Failed to retrieve authentication configuration'
}), 500
@auth_bp.route('/validate', methods=['POST'])
async def validate_token():
"""
Validate an access token and return user information
Expects: { "accessToken": "jwt-token" }
Returns: User information if valid
"""
try:
data = await request.get_json()
access_token = data.get('accessToken')
if not access_token:
return jsonify({
'error': 'invalid_request',
'message': 'Access token required'
}), 400
# Validate token
user_info = await msal_auth.validate_token(access_token)
if user_info:
return jsonify({
'valid': True,
'user': {
'id': user_info['oid'],
'username': user_info.get('preferred_username'),
'name': user_info.get('name'),
'roles': user_info.get('roles', ['user'])
}
})
else:
return jsonify({
'valid': False,
'error': 'invalid_token',
'message': 'Token is invalid or expired'
}), 401
except Exception as e:
logger.error(f"Token validation error: {e}")
return jsonify({
'error': 'validation_error',
'message': 'Failed to validate token'
}), 500
@auth_bp.route('/user', methods=['GET'])
@dev_mode_bypass
async def get_current_user_info():
"""
Get current authenticated user information
Returns current user details from token
"""
try:
user = await get_current_user()
if user:
return jsonify({
'user': {
'id': user['oid'],
'username': user.get('preferred_username'),
'name': user.get('name'),
'roles': user.get('roles', ['user'])
}
})
else:
return jsonify({
'error': 'unauthorized',
'message': 'No valid authentication found'
}), 401
except Exception as e:
logger.error(f"Failed to get user info: {e}")
return jsonify({
'error': 'server_error',
'message': 'Failed to retrieve user information'
}), 500
@auth_bp.route('/logout', methods=['POST'])
async def logout():
"""
Get logout URL for proper session termination
Returns logout URL for frontend redirect
"""
try:
data = await request.get_json() or {}
redirect_uri = data.get('redirectUri')
logout_url = await msal_auth.get_logout_url(redirect_uri)
return jsonify({
'logoutUrl': logout_url
})
except Exception as e:
logger.error(f"Logout error: {e}")
return jsonify({
'error': 'logout_error',
'message': 'Failed to generate logout URL'
}), 500