Spaces:
Sleeping
Sleeping
Download auth.py from AndreaNotes1/ayn: direct link, hf CLI and curl.
- Browser
- Download file 1.96 kB
-
https://huggingface.co/spaces/AndreaNotes1/ayn/resolve/main/auth.py
- Command line
-
hf download hf://spaces/AndreaNotes1/ayn/auth.py
-
curl -L -o auth.py https://huggingface.co/spaces/AndreaNotes1/ayn/resolve/main/auth.py
1.96 kB
| """ | |
| Handles password hashing and JWT issuing/validation for user login. | |
| """ | |
| from datetime import datetime, timedelta, timezone | |
| from typing import Optional | |
| import bcrypt | |
| from fastapi import Depends, HTTPException, status | |
| from fastapi.security import OAuth2PasswordBearer | |
| from jose import JWTError, jwt | |
| from config import settings | |
| from database import users_collection | |
| oauth2_scheme = OAuth2PasswordBearer(tokenUrl="api/auth/login") | |
| # bcrypt has a hard 72-byte limit on the input; longer passwords are truncated | |
| # before hashing (this matches bcrypt's own behavior, so it's safe either way). | |
| _MAX_PASSWORD_BYTES = 72 | |
| def hash_password(password: str) -> str: | |
| pw_bytes = password.encode("utf-8")[:_MAX_PASSWORD_BYTES] | |
| hashed = bcrypt.hashpw(pw_bytes, bcrypt.gensalt()) | |
| return hashed.decode("utf-8") | |
| def verify_password(plain: str, hashed: str) -> bool: | |
| pw_bytes = plain.encode("utf-8")[:_MAX_PASSWORD_BYTES] | |
| return bcrypt.checkpw(pw_bytes, hashed.encode("utf-8")) | |
| def create_access_token(subject: str) -> str: | |
| expire = datetime.now(timezone.utc) + timedelta(minutes=settings.JWT_EXPIRE_MINUTES) | |
| payload = {"sub": subject, "exp": expire} | |
| return jwt.encode(payload, settings.JWT_SECRET, algorithm=settings.JWT_ALGORITHM) | |
| async def get_current_user(token: str = Depends(oauth2_scheme)) -> dict: | |
| credentials_exception = HTTPException( | |
| status_code=status.HTTP_401_UNAUTHORIZED, | |
| detail="Could not validate credentials", | |
| headers={"WWW-Authenticate": "Bearer"}, | |
| ) | |
| try: | |
| payload = jwt.decode(token, settings.JWT_SECRET, algorithms=[settings.JWT_ALGORITHM]) | |
| user_email: Optional[str] = payload.get("sub") | |
| if user_email is None: | |
| raise credentials_exception | |
| except JWTError: | |
| raise credentials_exception | |
| user = await users_collection().find_one({"email": user_email}) | |
| if user is None: | |
| raise credentials_exception | |
| return user | |