50 lines
1.9 KiB
Python
50 lines
1.9 KiB
Python
from collections.abc import Callable
|
|
|
|
from fastapi import Depends, HTTPException, status
|
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.database import get_db
|
|
from app.models import PersonRole, Personnel, Role
|
|
from app.security import verify_token
|
|
from app.services.serializers import temporary_expired
|
|
|
|
bearer = HTTPBearer(auto_error=False)
|
|
|
|
|
|
def current_user(
|
|
credentials: HTTPAuthorizationCredentials | None = Depends(bearer),
|
|
db: Session = Depends(get_db),
|
|
) -> Personnel:
|
|
if credentials is None:
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="未登录")
|
|
|
|
try:
|
|
payload = verify_token(credentials.credentials)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="登录已失效") from exc
|
|
|
|
phone = payload.get("sub")
|
|
try:
|
|
role = Role(payload.get("role"))
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="角色无效") from exc
|
|
user = db.get(Personnel, phone)
|
|
if user is None:
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="人员不存在")
|
|
if temporary_expired(user):
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="临时工已过期,请微信授权续期")
|
|
if db.get(PersonRole, {"phone": phone, "role": role}) is None:
|
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="角色不存在")
|
|
user.role = role
|
|
return user
|
|
|
|
|
|
def require_roles(*roles: Role) -> Callable[[Personnel], Personnel]:
|
|
def checker(user: Personnel = Depends(current_user)) -> Personnel:
|
|
if user.role not in roles:
|
|
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="无权限")
|
|
return user
|
|
|
|
return checker
|