Arreglos de seguridad e historial
This commit is contained in:
@@ -32,7 +32,7 @@ class DoCMFRequest(BaseModel):
|
|||||||
core = info.data.get("core")
|
core = info.data.get("core")
|
||||||
if core:
|
if core:
|
||||||
a, b = 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.")
|
raise ValueError("El núcleo debe estar dentro del soporte.")
|
||||||
return v
|
return v
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,13 @@ from api.database.mongodb import users_collection
|
|||||||
from api.models.user_models import UserCreate, UserLogin
|
from api.models.user_models import UserCreate, UserLogin
|
||||||
from api.utils.security import hash_password, verify_password, generate_token
|
from api.utils.security import hash_password, verify_password, generate_token
|
||||||
from bson import ObjectId
|
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"])
|
router = APIRouter(prefix="/auth", tags=["auth"])
|
||||||
|
|
||||||
@@ -87,3 +94,23 @@ async def logout_user(user_id: str):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return {"message": "Sesión cerrada correctamente"}
|
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"],
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,34 +1,31 @@
|
|||||||
from fastapi import APIRouter, HTTPException, status
|
from fastapi import APIRouter, HTTPException, status, Depends
|
||||||
from typing import List
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from bson import ObjectId
|
from bson import ObjectId
|
||||||
|
|
||||||
from api.database.mongodb import users_collection
|
from api.database.mongodb import users_collection
|
||||||
from api.models.user_models import FuzzyTerm, HistoryCreateRequest
|
from api.models.user_models import FuzzyTerm, HistoryCreateRequest
|
||||||
|
from api.utils.security import get_current_user
|
||||||
|
|
||||||
router = APIRouter(prefix="/history", tags=["history"])
|
router = APIRouter(prefix="/history", tags=["history"])
|
||||||
|
|
||||||
|
|
||||||
@router.post("/{user_id}/add")
|
@router.post("/add")
|
||||||
async def add_history_item(user_id: str, data: HistoryCreateRequest):
|
async def add_history_item(
|
||||||
user = await users_collection.find_one({"_id": ObjectId(user_id)})
|
data: HistoryCreateRequest,
|
||||||
if not user:
|
current_user: dict = Depends(get_current_user),
|
||||||
raise HTTPException(
|
):
|
||||||
status_code=status.HTTP_404_NOT_FOUND,
|
user_id = current_user["_id"]
|
||||||
detail="Usuario no encontrado",
|
|
||||||
)
|
|
||||||
|
|
||||||
history_item_id = ObjectId()
|
history_item_id = ObjectId()
|
||||||
|
|
||||||
history_item = {
|
history_item = {
|
||||||
"_id": history_item_id,
|
"_id": history_item_id,
|
||||||
"name": data.name, # ← nuevo campo
|
"name": data.name,
|
||||||
"created_at": datetime.utcnow(),
|
"created_at": datetime.utcnow(),
|
||||||
"results": [r.dict() for r in data.results],
|
"results": [r.dict() for r in data.results],
|
||||||
}
|
}
|
||||||
|
|
||||||
await users_collection.update_one(
|
await users_collection.update_one(
|
||||||
{"_id": ObjectId(user_id)},
|
{"_id": user_id},
|
||||||
{"$push": {"history": history_item}},
|
{"$push": {"history": history_item}},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -38,18 +35,15 @@ async def add_history_item(user_id: str, data: HistoryCreateRequest):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/delete/{history_item_id}")
|
||||||
@router.delete("/{user_id}/delete/{history_item_id}")
|
async def delete_history_item(
|
||||||
async def delete_history_item(user_id: str, history_item_id: str):
|
history_item_id: str,
|
||||||
user = await users_collection.find_one({"_id": ObjectId(user_id)})
|
current_user: dict = Depends(get_current_user),
|
||||||
if not user:
|
):
|
||||||
raise HTTPException(
|
user_id = current_user["_id"]
|
||||||
status_code=status.HTTP_404_NOT_FOUND,
|
|
||||||
detail="Usuario no encontrado",
|
|
||||||
)
|
|
||||||
|
|
||||||
result = await users_collection.update_one(
|
result = await users_collection.update_one(
|
||||||
{"_id": ObjectId(user_id)},
|
{"_id": user_id},
|
||||||
{"$pull": {"history": {"_id": ObjectId(history_item_id)}}},
|
{"$pull": {"history": {"_id": ObjectId(history_item_id)}}},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import secrets
|
import secrets
|
||||||
from passlib.context import CryptContext
|
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")
|
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:
|
def generate_token() -> str:
|
||||||
return secrets.token_hex(32) # 64 caracteres seguros
|
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
|
||||||
Reference in New Issue
Block a user