Compare commits

...

15 Commits

3 changed files with 48 additions and 9 deletions

View File

@@ -12,11 +12,20 @@ from ..dependencies import database, cookie
SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
oauth2_scheme = cookie.OAuth2PasswordBearerWithCookie(tokenUrl="token")
def create_access_token(data: dict, expires_delta: timedelta | None = None):
to_encode = data.copy()
expire = datetime.utcnow() + (expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
def verify_password(plain_password, hashed_password):
return pwd_context.verify(plain_password, hashed_password)

View File

@@ -4,7 +4,7 @@ from ..dependencies import users_token, database, mail
from ..models import users, email
from fastapi.responses import JSONResponse, HTMLResponse
from fastapi_mail import MessageSchema, MessageType, FastMail
import random, os
import random, os, bcrypt
router = APIRouter()
@@ -68,26 +68,52 @@ async def reset_password(request: Request, key: str | None = None, email: str |
detail="Parameters 'key' and 'email' are required"
)
# Vérifier que la clé correspond à celle stockée dans Redis
# Récupérer la clé hachée depuis Redis
key_hashed = database.connect_redis.get(email)
if key_hashed is None or key_hashed != key:
if key_hashed is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Key is invalid or expired"
detail="Invalid or expired reset key"
)
# Redis stocke les valeurs en `bytes`, donc il faut décoder si nécessaire
if isinstance(key_hashed, bytes):
key_hashed = key_hashed.decode()
# Vérifier que la clé en clair correspond au hash stocké
if not bcrypt.checkpw(key.encode(), key_hashed.encode()):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Invalid reset key"
)
# Afficher la page HTML de réinitialisation du mot de passe
return templates.TemplateResponse("reset_password.html", {"request": request, "email": email, "key": key})
@router.post("/password/update", tags=["password"])
async def update_password(request: Request, email: str = Form(...), key: str = Form(...), new_password: str = Form(...)): # Vérification du token dans Redis
# Récupérer la clé hachée depuis Redis
key_hashed = database.connect_redis.get(email)
if key_hashed is None or key_hashed.decode() != key:
if key_hashed is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Key is invalid or expired"
detail="Invalid or expired reset key"
)
# Redis stocke les valeurs en `bytes`, donc il faut décoder si nécessaire
if isinstance(key_hashed, bytes):
key_hashed = key_hashed.decode()
# Vérifier que la clé en clair correspond au hash stocké
if not bcrypt.checkpw(key.encode(), key_hashed.encode()):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Invalid reset key"
)
# Recherche de l'utilisateur dans la base de données

View File

@@ -1,7 +1,7 @@
from datetime import datetime, timedelta
from typing import Annotated
from fastapi import Depends, FastAPI, HTTPException, status, APIRouter
from fastapi import Depends, FastAPI, HTTPException, status, APIRouter, Form
from fastapi.responses import JSONResponse
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from ..dependencies import users_token, permissions_checker
@@ -13,15 +13,19 @@ ACCESS_TOKEN_EXPIRE_MINUTES = 30
@router.post("/token", tags=["token"])
async def login_for_access_token(
form_data: Annotated[OAuth2PasswordRequestForm, Depends()]):
form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
remember_me: bool = Form(False)):
user = users_token.authenticate_user(form_data.username, form_data.password)
expires_access_token_time = ACCESS_TOKEN_EXPIRE_MINUTES
if remember_me:
expires_access_token_time=120
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Bearer"},
)
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
access_token_expires = timedelta(minutes=expires_access_token_time)
access_token = users_token.create_access_token(
data={"sub": user.username}, expires_delta=access_token_expires
)