""" 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