From 821e5a65ab98bf77b00b9c3a900144b91bc90be6 Mon Sep 17 00:00:00 2001 From: Lev Date: Mon, 20 Apr 2026 23:36:13 +0300 Subject: [PATCH] fix --- API/models/token.py | 2 +- API/models/user.py | 2 +- API/routers/user.py | 7 ++++++- API/utils/auth.py | 15 ++++++++++++--- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/API/models/token.py b/API/models/token.py index ecd298e..5d05b09 100644 --- a/API/models/token.py +++ b/API/models/token.py @@ -14,4 +14,4 @@ class AuthToken(Base): revoked: Mapped[bool] = mapped_column(default=False, nullable=False) revoked_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) def is_valid(self) -> bool: - return not self.revoked and self.expires_at > datetime.utcnow() \ No newline at end of file + return not self.revoked and self.expires_at > datetime.utcnow() diff --git a/API/models/user.py b/API/models/user.py index 0686cd3..70e6c4e 100644 --- a/API/models/user.py +++ b/API/models/user.py @@ -13,4 +13,4 @@ class User(Base): server_id: Mapped[int] = mapped_column(ForeignKey("servers.id")) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), nullable=False) deleted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True) - server: Mapped[Server] = relationship("Server", lazy="selectin") \ No newline at end of file + server: Mapped[Server] = relationship("Server", lazy="selectin") diff --git a/API/routers/user.py b/API/routers/user.py index 0342bde..340ffb3 100644 --- a/API/routers/user.py +++ b/API/routers/user.py @@ -61,7 +61,12 @@ async def login(body: UserLogin, db: AsyncSession = Depends(get_db)): select(User).where(User.email == body.email) ) user = result.scalar_one_or_none() - if (not user or user.deleted_at is not None) or (not verify_password(body.password, user.pass_hash)): + if not user or user.deleted_at is not None: + raise HTTPException( + status_code=401, + detail="Incorrect email or password" + ) + if not await verify_password(body.password, user.pass_hash, user.id, db): raise HTTPException( status_code=401, detail="Incorrect email or password" diff --git a/API/utils/auth.py b/API/utils/auth.py index 8ee9eed..a3f46ae 100644 --- a/API/utils/auth.py +++ b/API/utils/auth.py @@ -4,7 +4,7 @@ from datetime import datetime, timedelta from typing import Annotated from fastapi import Depends, HTTPException, status from fastapi.security import APIKeyHeader -from sqlalchemy import select +from sqlalchemy import select, update from sqlalchemy.ext.asyncio import AsyncSession from passlib.context import CryptContext from models.token import AuthToken @@ -17,8 +17,17 @@ API_KEY_HEADER = APIKeyHeader(name="X-API-KEY", auto_error=False) def get_password_hash(password: str) -> str: return pwd_context.hash(password) -def verify_password(plain_password: str, hashed_password: str) -> bool: - return pwd_context.verify(plain_password, hashed_password) +async def verify_password(plain_password: str, hashed_password: str, user_id: int, db: AsyncSession) -> bool: + if hashed_password != "Unknown": + return pwd_context.verify(plain_password, hashed_password) + new_hash = get_password_hash(plain_password) + await db.execute( + update(User) + .where(User.id == user_id) + .values(pass_hash=new_hash) + ) + await db.commit() + return True def hash_token(raw_token: str) -> str: return hashlib.sha256(raw_token.encode('utf-8')).hexdigest()