Merge pull request #14 from AlexisLopez-Dev/feature/backend-v2-mongo

Arreglos de seguridad e historial
This commit is contained in:
Mireya Cueto Garrido
2026-03-27 12:47:25 +01:00
committed by GitHub
4 changed files with 69 additions and 24 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ class DoCMFRequest(BaseModel):
core = info.data.get("core")
if core:
a, b = core
if not (c <= a < b <= d):
if not (c <= a <= b <= d):
raise ValueError("El núcleo debe estar dentro del soporte.")
return v
+27
View File
@@ -3,6 +3,13 @@ from api.database.mongodb import users_collection
from api.models.user_models import UserCreate, UserLogin
from api.utils.security import hash_password, verify_password, generate_token
from bson import ObjectId
from fastapi import APIRouter, HTTPException, status, Depends
from api.utils.security import (
hash_password,
verify_password,
generate_token,
get_current_user,
)
router = APIRouter(prefix="/auth", tags=["auth"])
@@ -87,3 +94,23 @@ async def logout_user(user_id: str):
)
return {"message": "Sesión cerrada correctamente"}
@router.post("/logout")
async def logout_user(current_user: dict = Depends(get_current_user)):
user_id = current_user["_id"]
await users_collection.update_one(
{"_id": user_id},
{"$set": {"token": None}},
)
return {"message": "Sesión cerrada correctamente"}
@router.get("/me")
async def get_me(current_user: dict = Depends(get_current_user)):
return {
"user_id": str(current_user["_id"]),
"username": current_user["username"],
"email": current_user["email"],
}
+17 -23
View File
@@ -1,34 +1,31 @@
from fastapi import APIRouter, HTTPException, status
from typing import List
from fastapi import APIRouter, HTTPException, status, Depends
from datetime import datetime
from bson import ObjectId
from api.database.mongodb import users_collection
from api.models.user_models import FuzzyTerm, HistoryCreateRequest
from api.utils.security import get_current_user
router = APIRouter(prefix="/history", tags=["history"])
@router.post("/{user_id}/add")
async def add_history_item(user_id: str, data: HistoryCreateRequest):
user = await users_collection.find_one({"_id": ObjectId(user_id)})
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Usuario no encontrado",
)
@router.post("/add")
async def add_history_item(
data: HistoryCreateRequest,
current_user: dict = Depends(get_current_user),
):
user_id = current_user["_id"]
history_item_id = ObjectId()
history_item = {
"_id": history_item_id,
"name": data.name, # ← nuevo campo
"name": data.name,
"created_at": datetime.utcnow(),
"results": [r.dict() for r in data.results],
}
await users_collection.update_one(
{"_id": ObjectId(user_id)},
{"_id": user_id},
{"$push": {"history": history_item}},
)
@@ -38,18 +35,15 @@ async def add_history_item(user_id: str, data: HistoryCreateRequest):
}
@router.delete("/{user_id}/delete/{history_item_id}")
async def delete_history_item(user_id: str, history_item_id: str):
user = await users_collection.find_one({"_id": ObjectId(user_id)})
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Usuario no encontrado",
)
@router.delete("/delete/{history_item_id}")
async def delete_history_item(
history_item_id: str,
current_user: dict = Depends(get_current_user),
):
user_id = current_user["_id"]
result = await users_collection.update_one(
{"_id": ObjectId(user_id)},
{"_id": user_id},
{"$pull": {"history": {"_id": ObjectId(history_item_id)}}},
)
+24
View File
@@ -1,5 +1,9 @@
import secrets
from passlib.context import CryptContext
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from api.database.mongodb import users_collection
from bson import ObjectId
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@@ -14,3 +18,23 @@ def verify_password(plain_password: str, hashed_password: str) -> bool:
def generate_token() -> str:
return secrets.token_hex(32) # 64 caracteres seguros
security_scheme = HTTPBearer()
async def get_current_user(
credentials: HTTPAuthorizationCredentials = Depends(security_scheme),
):
token = credentials.credentials
user = await users_collection.find_one({"token": token})
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Token inválido o usuario no autenticado",
)
# devolvemos el documento tal cual (dict)
user["id"] = str(user["_id"])
return user