This commit is contained in:
2025-10-24 14:54:44 -05:00
parent cb06217ef7
commit 6a58e19b10
16 changed files with 1172 additions and 138 deletions

View File

@@ -1,14 +1,14 @@
"""
Users API routes
"""
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi import APIRouter, Depends, HTTPException, status, Request
from typing import List
from pydantic import BaseModel
import hashlib
from sqlalchemy.orm import Session
from ..database import SessionLocal
from ..models import User, UserRole
from ..models import User, UserRole, Tenant
from ..config.settings import settings
router = APIRouter()
@@ -42,22 +42,42 @@ def hash_password(password: str) -> str:
return hashlib.sha256(password.encode()).hexdigest()
@router.get("/", response_model=List[UserResponse])
async def get_users(skip: int = 0, limit: int = 100, db: Session = Depends(SessionLocal)):
"""Get all users"""
users = db.query(User).offset(skip).limit(limit).all()
async def get_users(skip: int = 0, limit: int = 100, db: Session = Depends(SessionLocal), request: Request = None):
"""Get all users for the current tenant"""
tenant_id = getattr(request.state, 'tenant_id', None)
if not tenant_id and settings.MULTI_TENANT_ENABLED:
raise HTTPException(status_code=400, detail="Tenant ID is required")
query = db.query(User)
if settings.MULTI_TENANT_ENABLED:
query = query.filter(User.tenant_id == tenant_id)
users = query.offset(skip).limit(limit).all()
return users
@router.get("/{user_id}", response_model=UserResponse)
async def get_user(user_id: int, db: Session = Depends(SessionLocal)):
async def get_user(user_id: int, db: Session = Depends(SessionLocal), request: Request = None):
"""Get a specific user"""
user = db.query(User).filter(User.id == user_id).first()
tenant_id = getattr(request.state, 'tenant_id', None)
if not tenant_id and settings.MULTI_TENANT_ENABLED:
raise HTTPException(status_code=400, detail="Tenant ID is required")
query = db.query(User).filter(User.id == user_id)
if settings.MULTI_TENANT_ENABLED:
query = query.filter(User.tenant_id == tenant_id)
user = query.first()
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user
@router.post("/", response_model=UserResponse)
async def create_user(user: UserCreate, db: Session = Depends(SessionLocal)):
async def create_user(user: UserCreate, db: Session = Depends(SessionLocal), request: Request = None):
"""Create a new user"""
tenant_id = getattr(request.state, 'tenant_id', None)
if not tenant_id and settings.MULTI_TENANT_ENABLED:
raise HTTPException(status_code=400, detail="Tenant ID is required")
# Check if user already exists
existing_user = db.query(User).filter(
(User.email == user.email) | (User.username == user.username)
@@ -73,7 +93,7 @@ async def create_user(user: UserCreate, db: Session = Depends(SessionLocal)):
username=user.username,
hashed_password=hashed_pwd,
role=user.role.value,
tenant_id=1 # Default tenant, in real app would come from context
tenant_id=tenant_id # Use the current tenant
)
db.add(db_user)
db.commit()
@@ -81,9 +101,16 @@ async def create_user(user: UserCreate, db: Session = Depends(SessionLocal)):
return db_user
@router.put("/{user_id}", response_model=UserResponse)
async def update_user(user_id: int, user_update: UserUpdate, db: Session = Depends(SessionLocal)):
async def update_user(user_id: int, user_update: UserUpdate, db: Session = Depends(SessionLocal), request: Request = None):
"""Update a user"""
db_user = db.query(User).filter(User.id == user_id).first()
tenant_id = getattr(request.state, 'tenant_id', None)
if not tenant_id and settings.MULTI_TENANT_ENABLED:
raise HTTPException(status_code=400, detail="Tenant ID is required")
db_user = db.query(User).filter(
User.id == user_id,
User.tenant_id == tenant_id # Ensure user belongs to current tenant
).first()
if not db_user:
raise HTTPException(status_code=404, detail="User not found")
@@ -100,9 +127,16 @@ async def update_user(user_id: int, user_update: UserUpdate, db: Session = Depen
return db_user
@router.delete("/{user_id}")
async def delete_user(user_id: int, db: Session = Depends(SessionLocal)):
async def delete_user(user_id: int, db: Session = Depends(SessionLocal), request: Request = None):
"""Delete a user"""
db_user = db.query(User).filter(User.id == user_id).first()
tenant_id = getattr(request.state, 'tenant_id', None)
if not tenant_id and settings.MULTI_TENANT_ENABLED:
raise HTTPException(status_code=400, detail="Tenant ID is required")
db_user = db.query(User).filter(
User.id == user_id,
User.tenant_id == tenant_id # Ensure user belongs to current tenant
).first()
if not db_user:
raise HTTPException(status_code=404, detail="User not found")