188 lines
6.2 KiB
Python
188 lines
6.2 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, Query, Request, Header, status
|
|
#
|
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
|
from sqlalchemy.orm import Session
|
|
from typing import Optional, List
|
|
#
|
|
from database import get_db
|
|
from app.core.auth import get_current_user
|
|
from app.modules.users.models import Users
|
|
#
|
|
from app.modules.users.schema import UserCreate, UserResponse, UserLogin, LoginResponse, DeleteResponse, UpdateUser
|
|
from app.modules.users.services import UserCrudService
|
|
from app.core.security import create_access_token, verify_password
|
|
|
|
router = APIRouter(prefix="/users", tags=["users"])
|
|
security = HTTPBearer()
|
|
|
|
#================ Login ====================
|
|
@router.post("/login", response_model=LoginResponse)
|
|
async def login(
|
|
login_data: UserLogin,
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""Authenticate user and return JWT token"""
|
|
|
|
user = db.query(Users).filter(Users.email == login_data.email).first()
|
|
|
|
#check email
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code = status.HTTP_401_UNAUTHORIZED,
|
|
detail="Credentials invalid - user not found",
|
|
headers={"WWW-Authenticate": "Bearer"},
|
|
)
|
|
|
|
|
|
#check password ...
|
|
if not verify_password(login_data.password, user.password):
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="Invalid credentials = worng password",
|
|
headers={"WWW-Athenticate": "Bearer"}
|
|
)
|
|
|
|
#check is active
|
|
if not user.is_active:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="This user is ianctive, contact with support"
|
|
)
|
|
|
|
#update last login
|
|
from datetime import datetime
|
|
user.last_login = datetime.utcnow()
|
|
db.commit()
|
|
|
|
#create token
|
|
token_data = {
|
|
"sub": str(user.id),
|
|
"email": user.email,
|
|
"user_type": user.tipo_usuario,
|
|
"rol_operativo": user.rol_operativo
|
|
}
|
|
access_token = create_access_token(token_data)
|
|
|
|
return LoginResponse(access_token=access_token, token_type="bearer")
|
|
|
|
|
|
|
|
#================ Register ====================
|
|
|
|
@router.post("/register", response_model=UserResponse)
|
|
async def register(data: UserCreate, db: Session = Depends(get_db)):
|
|
|
|
user_count = db.query(Users).count()
|
|
|
|
if user_count == 0:
|
|
service = UserCrudService()
|
|
return UserCrudService.create_user(db = db, user_create=data, current_user=None)
|
|
else:
|
|
raise HTTPException(
|
|
status_code=403,
|
|
detail="Root user already exists, use create_users enpoint"
|
|
)
|
|
|
|
#================ Create User ====================
|
|
@router.post("/create_users", response_model=UserResponse)
|
|
async def new_user(
|
|
data: UserCreate,
|
|
db: Session = Depends(get_db),
|
|
credentials: HTTPAuthorizationCredentials = Depends(security)
|
|
):
|
|
|
|
"""Create a new user - Requeres authentication """
|
|
|
|
from app.core.auth import AuthService
|
|
|
|
token = credentials.credentials
|
|
auth_service = AuthService()
|
|
payload = auth_service.decode_token(token)
|
|
user_id = int(payload.get("sub"))
|
|
current_user = db.query(Users).filter(Users.id == user_id).first()
|
|
|
|
|
|
if not current_user:
|
|
raise HTTPException(
|
|
status_code=401,
|
|
detail="User not found - invalid token"
|
|
)
|
|
|
|
if current_user.tipo_usuario not in ["root", "admin"]:
|
|
raise HTTPException(status_code=403, detail="you dont have permission to create users")
|
|
|
|
if current_user.tipo_usuario == "admin" and data.tipo_usuario != "user":
|
|
raise HTTPException(status_code=403, detail="Admin can only create users type user")
|
|
|
|
return UserCrudService.create_user(
|
|
db = db, user_create = data, current_user = current_user
|
|
)
|
|
|
|
#================ Get Users ====================
|
|
@router.get("/get", response_model=List[UserResponse])
|
|
def obtain_users(
|
|
db: Session = Depends(get_db),
|
|
current_user: Users = Depends(get_current_user),
|
|
skip: int = Query(0, ge=0, description="Number of records to skip for pagination"),
|
|
limit: int = Query(100, ge=1, le= 1000, description="Maximun number of records to return")
|
|
):
|
|
"""Get a list of user with pagination - requeres authentication"""
|
|
return UserCrudService.get_users(db = db, skip=skip, limit=limit)
|
|
|
|
#================ Delete Users ====================
|
|
@router.delete("/delete/{user_id}", response_model=DeleteResponse)
|
|
async def delete(
|
|
db:Session = Depends(get_db),
|
|
user_id= int,
|
|
current_user: Users = Depends(get_current_user)
|
|
):
|
|
"""Delete a user by id"""
|
|
|
|
current_user = db.query(Users).filter(Users.id == user_id).first()
|
|
|
|
if current_user.tipo_usuario not in ["root", "admin"]:
|
|
raise HTTPException(status_code=403,
|
|
detail="You dont have permitions to delete ")
|
|
try:
|
|
UserCrudService.delete_user(db = db, user_id=user_id, current_user=current_user)
|
|
return {"message": "ok"}
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=400, detail=str(e))
|
|
|
|
#================ Update Users ====================
|
|
|
|
@router.patch("/update/{user_id}", response_model=UserResponse)
|
|
async def user_update(
|
|
user_id: int,
|
|
data: UpdateUser,
|
|
db: Session = Depends(get_db),
|
|
current_user: Users = Depends(get_current_user)
|
|
):
|
|
""" Update existing user"""
|
|
|
|
user = db.query(Users).filter(Users.id == user_id).first()
|
|
|
|
current_user = db.query(Users).filter(Users.id == user_id).first()
|
|
|
|
if not user:
|
|
raise ValueError("Usuario no encontrado")
|
|
|
|
if current_user.id != user_id:
|
|
if current_user.tipo_usuario not in ["root", "admin"]:
|
|
raise PermissionError("Admin only can update user ur enterprise")
|
|
try:
|
|
updated_user = await UserCrudService.Update_user(db=db, user_id=user_id, user_data=data, current_user=current_user)
|
|
print(f"TIPO DE updated_user: {type(updated_user)}")
|
|
print(f"VALOR: {updated_user}")
|
|
print(f"ID: {updated_user.id if updated_user else 'None'}")
|
|
return UserResponse.model_validate(updated_user)
|
|
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=404, detail=str(e))
|
|
|
|
except PermissionError as e:
|
|
raise HTTPException(status_code=403, detail=str(e))
|
|
|
|
|
|
|
|
|