# 宇之然内容创作平台 - 安全模块 from datetime import datetime, timedelta from typing import Optional from jose import JWTError, jwt from passlib.context import CryptContext from fastapi.security import OAuth2PasswordBearer from fastapi import Depends, HTTPException, status from sqlalchemy.orm import Session from ..models import User from ..database import get_db # 密码加密 pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") # JWT配置 SECRET_KEY = "your-secret-key-here" # 生产环境应从环境变量读取 ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 10080 # 7天 oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/auth/login") def verify_password(plain_password: str, hashed_password: str) -> bool: """验证密码""" return pwd_context.verify(plain_password, hashed_password) def get_password_hash(password: str) -> str: """生成密码哈希""" return pwd_context.hash(password) def create_access_token(data: dict, expires_delta: Optional[timedelta] = None): """创建JWT token""" to_encode = data.copy() if expires_delta: expire = datetime.utcnow() + expires_delta else: expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) to_encode.update({"exp": expire}) encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) return encoded_jwt async def get_current_user( token: str = Depends(oauth2_scheme), db: Session = Depends(get_db) ) -> User: """获取当前用户""" credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="无效的认证凭据", headers={"WWW-Authenticate": "Bearer"}, ) try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) username: str = payload.get("sub") if username is None: raise credentials_exception except JWTError: raise credentials_exception user = db.query(User).filter(User.username == username).first() if user is None: raise credentials_exception return user async def get_current_active_user(current_user: User = Depends(get_current_user)): """获取活跃用户(简单检查)""" # 这里可以添加更多活跃性检查逻辑 return current_user async def get_current_admin_user(current_user: User = Depends(get_current_user)): """获取管理员用户""" if current_user.role != "admin": raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="权限不足,需要管理员角色" ) return current_user def create_audit_log( db: Session, user_id: int, action: str, resource_type: str = "", resource_id: int = None, details: str = "", ip_address: str = "", user_agent: str = "" ): """创建审计日志""" from ..models import AuditLog audit_log = AuditLog( user_id=user_id, action=action, resource_type=resource_type, resource_id=resource_id, details=details, ip_address=ip_address, user_agent=user_agent ) db.add(audit_log) db.commit()