💥 Removed default timedelta + fixed user_id in register + comment out the logout route (maybe unuseful) + added ObjectID format try except to every route that needs an id

master
Alix JEUDI--LEMOINE 4 months ago
parent 4271ce2110
commit 2418f613b5

@ -1,3 +1,4 @@
import bson
from fastapi import FastAPI, Depends, HTTPException, status from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
@ -15,7 +16,7 @@ import app.serializers as serializers # Import all serializers (detailed in __in
from app.models import User, Pin, Friend, Token, TokenData, HTTPError from app.models import User, Pin, Friend, Token, TokenData, HTTPError
# Import all DTOs (detailed in __init__.py) # Import all DTOs (detailed in __init__.py)
from app.dto import FriendAddDTO, FriendListDTO, UserDTO, UserRegisterDTO from app.dto import FriendAddDTO, FriendListDTO, UserDTO, UserRegisterDTO, PinDTO
# Contains all constants # Contains all constants
import app.config as config import app.config as config
@ -45,13 +46,10 @@ pins_collection = db["pins"]
friends_collection = db["friends"] friends_collection = db["friends"]
# Token management # Token management
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): def create_access_token(data: dict, expires_delta: timedelta):
to_encode = data.copy() to_encode = data.copy()
if expires_delta:
expire = datetime.now() + expires_delta expire = datetime.now() + expires_delta
else:
expire = datetime.now() + timedelta(minutes=15)
to_encode.update({"exp": expire}) to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, config.SECRET_KEY, algorithm=config.ALGORITHM) encoded_jwt = jwt.encode(to_encode, config.SECRET_KEY, algorithm=config.ALGORITHM)
@ -101,7 +99,7 @@ async def register(user: UserRegisterDTO):
access_token_expires = timedelta(minutes=config.ACCESS_TOKEN_EXPIRE_MINUTES) access_token_expires = timedelta(minutes=config.ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(data={"sub": user.username}, expires_delta=access_token_expires) access_token = create_access_token(data={"sub": user.username}, expires_delta=access_token_expires)
return {"access_token": access_token, "token_type": "bearer", "user_id": str(user_id)} return {"access_token": access_token, "token_type": "bearer", "user_id": str(user_id.inserted_id)}
@app.post( @app.post(
path="/login", path="/login",
@ -122,20 +120,28 @@ async def login(form_data: OAuth2PasswordRequestForm = Depends()):
return {"access_token": access_token, "token_type": "bearer", "user_id": str(user["_id"])} return {"access_token": access_token, "token_type": "bearer", "user_id": str(user["_id"])}
""" Is it really usefull ? idk.
@app.get( @app.get(
path="/logout", path="/logout",
responses={401: {"model": HTTPError}} responses={401: {"model": HTTPError}}
) )
async def logout(current_user: User = Depends(get_current_user)): async def logout(current_user: User = Depends(get_current_user)):
# TODO: find usecase / what to do ??
return {"message": "Logged out"} return {"message": "Logged out"}
"""
@app.get( @app.get(
path="/pin/{id}", path="/pin/{id}",
responses={401: {"model": HTTPError}, 404: {"model": HTTPError}} responses={401: {"model": HTTPError}, 404: {"model": HTTPError}, 422: {"model": HTTPError}}
) )
async def get_pin(id: str, current_user: User = Depends(get_current_user)): async def get_pin(id: str, current_user: User = Depends(get_current_user)):
try:
pin = pins_collection.find_one({"_id": ObjectId(id)}) pin = pins_collection.find_one({"_id": ObjectId(id)})
except bson.errors.InvalidId:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="The ObjectID is misformatted"
)
if pin is None: if pin is None:
raise HTTPException(status_code=404, detail="Pin not found") raise HTTPException(status_code=404, detail="Pin not found")
@ -143,10 +149,17 @@ async def get_pin(id: str, current_user: User = Depends(get_current_user)):
@app.patch( @app.patch(
path="/pin/{id}", path="/pin/{id}",
responses={401: {"model": HTTPError}, 404: {"model": HTTPError}} responses={401: {"model": HTTPError}, 404: {"model": HTTPError}, 422: {"model": HTTPError}}
) )
async def update_pin(id: str, pin: Pin, current_user: User = Depends(get_current_user)): async def update_pin(id: str, pin: PinDTO, current_user: User = Depends(get_current_user)):
try:
result = pins_collection.update_one({"_id": ObjectId(id)}, {"$set": pin.model_dump()}) result = pins_collection.update_one({"_id": ObjectId(id)}, {"$set": pin.model_dump()})
except bson.errors.InvalidId:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="The ObjectID is misformatted"
)
if result.matched_count == 0: if result.matched_count == 0:
raise HTTPException(status_code=404, detail="Pin not found") raise HTTPException(status_code=404, detail="Pin not found")
@ -156,7 +169,7 @@ async def update_pin(id: str, pin: Pin, current_user: User = Depends(get_current
path="/pin/add", path="/pin/add",
responses={401: {"model": HTTPError}} responses={401: {"model": HTTPError}}
) )
async def add_pin(pin: Pin, current_user: User = Depends(get_current_user)): async def add_pin(pin: PinDTO, current_user: User = Depends(get_current_user)):
pin_id = pins_collection.insert_one(pin.model_dump()).inserted_id pin_id = pins_collection.insert_one(pin.model_dump()).inserted_id
return {"id": str(pin_id)} return {"id": str(pin_id)}
@ -175,13 +188,20 @@ def friend_not_found():
@app.get( @app.get(
path="/friend/{id}", path="/friend/{id}",
responses={401: {"model": HTTPError}, 404: {"model": HTTPError}} responses={401: {"model": HTTPError}, 404: {"model": HTTPError}, 422: {"model": HTTPError}}
) )
async def get_friend(id: str, current_user: User = Depends(get_current_user)): async def get_friend(id: str, current_user: User = Depends(get_current_user)):
try:
friend = friends_collection.find_one({"_id": ObjectId(id)}) friend = friends_collection.find_one({"_id": ObjectId(id)})
except bson.errors.InvalidId:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="The ObjectID is misformatted"
)
if friend is None: friend_not_found() if friend is None: friend_not_found()
return friend return serializers.friend_serialize(friend)
@app.post( @app.post(
path="/friend/add", path="/friend/add",
@ -191,8 +211,6 @@ async def add_friend(friend_to_add: FriendAddDTO, current_user: User = Depends(g
# TODO: test if exists # TODO: test if exists
friend: Friend = friend_to_add.model_dump() friend: Friend = friend_to_add.model_dump()
print(current_user)
if(current_user.uid == friend["friend_user_id"]): if(current_user.uid == friend["friend_user_id"]):
raise HTTPException( raise HTTPException(
status_code=status.HTTP_409_CONFLICT, status_code=status.HTTP_409_CONFLICT,
@ -205,30 +223,51 @@ async def add_friend(friend_to_add: FriendAddDTO, current_user: User = Depends(g
@app.delete( @app.delete(
path="/friend/{id}/delete", path="/friend/{id}/delete",
responses={401: {"model": HTTPError}, 404: {"model": HTTPError}} responses={401: {"model": HTTPError}, 404: {"model": HTTPError}, 422: {"model": HTTPError}}
) )
async def delete_friend(id: str, current_user: User = Depends(get_current_user)): async def delete_friend(id: str, current_user: User = Depends(get_current_user)):
try:
result = friends_collection.delete_one({"_id": ObjectId(id)}) result = friends_collection.delete_one({"_id": ObjectId(id)})
except bson.errors.InvalidId:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="The ObjectID is misformatted"
)
if result.deleted_count == 0: friend_not_found() if result.deleted_count == 0: friend_not_found()
return {"message": "Friend deleted"} return {"message": "Friend deleted"}
@app.patch( @app.patch(
path="/friend/{id}/accept", path="/friend/{id}/accept",
responses={401: {"model": HTTPError}, 404: {"model": HTTPError}} responses={401: {"model": HTTPError}, 404: {"model": HTTPError}, 422: {"model": HTTPError}}
) )
async def accept_friend(id: str, current_user: User = Depends(get_current_user)): async def accept_friend(id: str, current_user: User = Depends(get_current_user)):
try:
result = friends_collection.update_one({"_id": ObjectId(id)}, {"$set": {"status": "accepted"}}) result = friends_collection.update_one({"_id": ObjectId(id)}, {"$set": {"status": "accepted"}})
except bson.errors.InvalidId:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="The ObjectID is misformatted"
)
if result.matched_count == 0: friend_not_found() if result.matched_count == 0: friend_not_found()
return {"message": "Friend request accepted"} return {"message": "Friend request accepted"}
@app.post( @app.post(
path="/friend/{id}/deny", path="/friend/{id}/deny",
responses={401: {"model": HTTPError}, 404: {"model": HTTPError}} responses={401: {"model": HTTPError}, 404: {"model": HTTPError}, 422: {"model": HTTPError}}
) )
async def deny_friend(id: str, current_user: User = Depends(get_current_user)): async def deny_friend(id: str, current_user: User = Depends(get_current_user)):
try:
result = friends_collection.update_one({"_id": ObjectId(id)}, {"$set": {"status": "denied"}}) result = friends_collection.update_one({"_id": ObjectId(id)}, {"$set": {"status": "denied"}})
except bson.errors.InvalidId:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail="The ObjectID is misformatted"
)
if result.matched_count == 0: friend_not_found() if result.matched_count == 0: friend_not_found()
return {"message": "Friend request denied"} return {"message": "Friend request denied"}

Loading…
Cancel
Save