Files
bakery-ia/services/auth/app/api/users.py

119 lines
4.2 KiB
Python
Raw Normal View History

2025-07-17 19:03:11 +02:00
"""
User management API routes
"""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
2025-07-21 14:41:33 +02:00
from typing import Dict, Any
2025-07-18 14:41:39 +02:00
import structlog
2025-07-17 19:03:11 +02:00
from app.core.database import get_db
2025-07-20 08:33:23 +02:00
from app.schemas.auth import UserResponse, PasswordChange
2025-07-19 21:16:25 +02:00
from app.schemas.users import UserUpdate
2025-07-17 19:03:11 +02:00
from app.services.user_service import UserService
from app.models.users import User
2025-07-26 19:15:18 +02:00
from sqlalchemy.ext.asyncio import AsyncSession
2025-07-21 14:41:33 +02:00
# 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
)
2025-07-18 14:41:39 +02:00
logger = structlog.get_logger()
2025-07-26 18:46:52 +02:00
router = APIRouter(tags=["users"])
2025-07-17 19:03:11 +02:00
@router.get("/me", response_model=UserResponse)
async def get_current_user_info(
2025-07-21 14:41:33 +02:00
current_user: Dict[str, Any] = Depends(get_current_user_dep),
2025-07-17 19:03:11 +02:00
db: AsyncSession = Depends(get_db)
):
"""Get current user information"""
try:
2025-07-26 19:15:18 +02:00
# 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
)
2025-07-17 19:03:11 +02:00
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(
2025-07-19 21:16:25 +02:00
user_update: UserUpdate,
2025-07-21 20:43:17 +02:00
current_user: Dict[str, Any] = Depends(get_current_user_dep),
2025-07-17 19:03:11 +02:00
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"
)