from fastapi import APIRouter, HTTPException, status, Depends from models.auth_models import LoginRequest, LoginResponse from services.auth_service import auth_service, get_current_user from services.supabase_service import supabase_service from integrations.jira_service import JiraIntegrationService from config.settings import settings import logging logger = logging.getLogger(__name__) router = APIRouter(prefix="/auth", tags=["Authentication"]) @router.post("/login", response_model=LoginResponse) async def login(credentials: LoginRequest): """ Authenticate user with Jira credentials and return JWT token This endpoint verifies the user's Jira credentials and returns a JWT token that can be used for subsequent API requests. Args: credentials: User's Jira email, API token, and server URL Returns: LoginResponse: JWT access token and expiration info Raises: HTTPException: If credentials are invalid Example: ```json { "jira_email": "user@company.com", "jira_api_token": "your_jira_api_token", "jira_server_url": "https://yourcompany.atlassian.net" } ``` """ try: # Create access token (this also verifies credentials) access_token = auth_service.create_access_token(credentials) # Save credentials to Supabase for background syncing try: # We need the accountId to link webhooks later jira_service = JiraIntegrationService( jira_email=credentials.jira_email, jira_api_token=credentials.jira_api_token, jira_server_url=credentials.jira_server_url ) myself = jira_service.get_myself() account_id = myself.get("accountId") if account_id: success = supabase_service.save_user_credentials( email=credentials.jira_email, api_token=credentials.jira_api_token, server_url=credentials.jira_server_url, account_id=account_id ) if success: logger.info(f"Saved credentials for user {credentials.jira_email} with accountId {account_id}") else: logger.error(f"Failed to save credentials for user {credentials.jira_email} - Supabase check failed") else: logger.warning(f"Could not get accountId for user {credentials.jira_email}, credentials not saved for webhook use") except Exception as e: logger.error(f"Failed to save credentials to Supabase: {str(e)}") # We don't fail the login if saving credentials fails, but warn about it return LoginResponse( access_token=access_token, token_type="bearer", expires_in=settings.access_token_expire_minutes * 60 # Convert to seconds ) except HTTPException: # Re-raise HTTP exceptions from auth service raise except Exception as e: logger.error(f"Login error: {str(e)}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="An error occurred during login" ) @router.get("/me") async def get_current_user_info(current_user = Depends(get_current_user)): """ Get current authenticated user information Returns information about the currently authenticated user from their JWT token. This is useful for verifying authentication and checking token validity. Returns: dict: User information (excluding sensitive data like API token) """ return { "jira_email": current_user.jira_email, "jira_server_url": current_user.jira_server_url, "authenticated": True }