feat: AI Worker 平台 MVP v1.0.0 - 多租户/项目管理/AI Worker/任务编排/HITL审核/成本治理
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
"""Security utilities: JWT tokens, password hashing.
|
||||||
|
|
||||||
|
Uses bcrypt directly (passlib has compatibility issues with bcrypt>=4.1).
|
||||||
|
"""
|
||||||
|
from datetime import datetime, timedelta, timezone
|
||||||
|
from typing import Optional
|
||||||
|
from jose import jwt, JWTError
|
||||||
|
import bcrypt
|
||||||
|
from app.config import settings
|
||||||
|
|
||||||
|
|
||||||
|
def hash_password(password: str) -> str:
|
||||||
|
"""Hash a plaintext password using bcrypt."""
|
||||||
|
# bcrypt has a 72-byte limit, so we truncate
|
||||||
|
pwd_bytes = password.encode("utf-8")[:72]
|
||||||
|
salt = bcrypt.gensalt()
|
||||||
|
return bcrypt.hashpw(pwd_bytes, salt).decode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def verify_password(plain: str, hashed: str) -> bool:
|
||||||
|
"""Verify a plaintext password against its bcrypt hash."""
|
||||||
|
try:
|
||||||
|
pwd_bytes = plain.encode("utf-8")[:72]
|
||||||
|
hash_bytes = hashed.encode("utf-8")
|
||||||
|
return bcrypt.checkpw(pwd_bytes, hash_bytes)
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def create_access_token(
|
||||||
|
subject: str,
|
||||||
|
tenant_id: int,
|
||||||
|
role: str,
|
||||||
|
extra: Optional[dict] = None,
|
||||||
|
) -> str:
|
||||||
|
"""Create a JWT access token."""
|
||||||
|
now = datetime.now(timezone.utc)
|
||||||
|
expire = now + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
|
||||||
|
payload = {
|
||||||
|
"sub": subject,
|
||||||
|
"tid": tenant_id,
|
||||||
|
"role": role,
|
||||||
|
"iat": now,
|
||||||
|
"exp": expire,
|
||||||
|
}
|
||||||
|
if extra:
|
||||||
|
payload.update(extra)
|
||||||
|
return jwt.encode(payload, settings.SECRET_KEY, algorithm="HS256")
|
||||||
|
|
||||||
|
|
||||||
|
def decode_access_token(token: str) -> dict:
|
||||||
|
"""Decode and validate a JWT token. Raises JWTError on failure."""
|
||||||
|
return jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
|
||||||
Reference in New Issue
Block a user