sayAI / auth.py
WACATW's picture
Create auth.py
6bfebc3 verified
Raw History Blame Contribute Delete
2.59 kB
import os, json, sqlite3
from datetime import datetime, timedelta
from jose import JWTError, jwt
from passlib.context import CryptContext
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer
from huggingface_hub import HfApi
SECRET_KEY = os.environ.get("JWT_SECRET", "dev-secret-change-me")
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 60 * 24 * 7 # 7天
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
security = HTTPBearer()
DB_PATH = "/tmp/users.db"
BUCKET_ID = os.environ.get("HF_BUCKET_ID", "your-username/learning-platform-data")
def init_db():
conn = sqlite3.connect(DB_PATH)
conn.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
email TEXT,
created_at TEXT
)
""")
conn.commit()
conn.close()
# 尝试从 Buckets 恢复用户数据库
_restore_db_from_bucket()
def _restore_db_from_bucket():
try:
from huggingface_hub import hf_hub_download
path = hf_hub_download(
repo_id=BUCKET_ID.replace("/", "_"), # Buckets 访问方式
filename="users.db",
repo_type="bucket"
)
import shutil
shutil.copy(path, DB_PATH)
except Exception:
pass # 首次运行没有备份
def _backup_db_to_bucket():
try:
from huggingface_hub import upload_file
upload_file(
path_or_fileobj=DB_PATH,
path_in_repo="users.db",
repo_id=BUCKET_ID.replace("/", "_"),
repo_type="bucket"
)
except Exception:
pass
def hash_password(password: str) -> str:
return pwd_context.hash(password)
def verify_password(plain: str, hashed: str) -> bool:
return pwd_context.verify(plain, hashed)
def create_access_token(data: dict):
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
def get_current_user(credentials=Depends(security)):
token = credentials.credentials
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise HTTPException(status_code=401, detail="Invalid token")
return username
except JWTError:
raise HTTPException(status_code=401, detail="Invalid token")