Files
bakery-ia/services/auth/app/api/users.py
2025-07-26 19:15:18 +02:00

119 lines
4.2 KiB
Python

"""
User management API routes
"""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Dict, Any
import structlog
from app.core.database import get_db
from app.schemas.auth import UserResponse, PasswordChange
from app.schemas.users import UserUpdate
from app.services.user_service import UserService
from app.models.users import User
from sqlalchemy.ext.asyncio import AsyncSession
# Import unified authentication from shared library
from shared.auth.decorators import (
get_current_user_dep,
get_current_tenant_id_dep,
require_role # For admin-only endpoints
)
logger = structlog.get_logger()
router = APIRouter(tags=["users"])
@router.get("/me", response_model=UserResponse)
async def get_current_user_info(
current_user: Dict[str, Any] = Depends(get_current_user_dep),
db: AsyncSession = Depends(get_db)
):
"""Get current user information"""
try:
# Handle both User object (direct auth) and dict (from gateway headers)
if isinstance(current_user, dict):
# Coming from gateway headers - need to fetch user from DB
user_id = current_user.get("user_id")
if not user_id:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid user context"
)
# Fetch full user from database
from sqlalchemy import select
from app.models.users import User
result = await db.execute(select(User).where(User.id == user_id))
user = result.scalar_one_or_none()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
return UserResponse(
id=str(user.id),
email=user.email,
full_name=user.full_name,
is_active=user.is_active,
is_verified=user.is_verified,
phone=user.phone,
language=user.language,
timezone=user.timezone,
created_at=user.created_at,
last_login=user.last_login
)
else:
# Direct User object (when called directly)
return UserResponse(
id=str(current_user.id),
email=current_user.email,
full_name=current_user.full_name,
is_active=current_user.is_active,
is_verified=current_user.is_verified,
phone=current_user.phone,
language=current_user.language,
timezone=current_user.timezone,
created_at=current_user.created_at,
last_login=current_user.last_login
)
except Exception as e:
logger.error(f"Get current user error: {e}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to get user information"
)
@router.put("/me", response_model=UserResponse)
async def update_current_user(
user_update: UserUpdate,
current_user: Dict[str, Any] = Depends(get_current_user_dep),
db: AsyncSession = Depends(get_db)
):
"""Update current user information"""
try:
updated_user = await UserService.update_user(current_user.id, user_update, db)
return UserResponse(
id=str(updated_user.id),
email=updated_user.email,
full_name=updated_user.full_name,
is_active=updated_user.is_active,
is_verified=updated_user.is_verified,
phone=updated_user.phone,
language=updated_user.language,
timezone=updated_user.timezone,
created_at=updated_user.created_at,
last_login=updated_user.last_login
)
except HTTPException:
raise
except Exception as e:
logger.error(f"Update user error: {e}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to update user"
)