""" API 依賴注入 """ from typing import Generator from fastapi import Depends, HTTPException, status from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from sqlalchemy.orm import Session from app.core.database import SessionLocal from app.core.security import decode_token from app.models.employee import Employee # Bearer Token 安全機制 security = HTTPBearer() def get_db() -> Generator: """取得資料庫 Session""" db = SessionLocal() try: yield db finally: db.close() def get_current_user( credentials: HTTPAuthorizationCredentials = Depends(security), db: Session = Depends(get_db), ) -> Employee: """ 取得當前使用者 從 Authorization header 解析 JWT Token, 驗證並返回對應的員工物件。 """ token = credentials.credentials payload = decode_token(token) if not payload: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail={"code": "AUTH001", "message": "Token 無效"}, ) # 檢查 Token 類型 if payload.get("type") != "access": raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail={"code": "AUTH001", "message": "Token 類型錯誤"}, ) user_id = payload.get("sub") if not user_id: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail={"code": "AUTH001", "message": "Token 無效"}, ) user = db.query(Employee).filter(Employee.id == int(user_id)).first() if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail={"code": "AUTH001", "message": "使用者不存在"}, ) if user.status != "active": raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail={"code": "AUTH004", "message": "帳號已停用"}, ) return user def get_current_manager( current_user: Employee = Depends(get_current_user), ) -> Employee: """取得當前主管使用者""" if not current_user.is_manager: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail={"code": "AUTH003", "message": "權限不足,需要主管權限"}, ) return current_user def get_current_admin( current_user: Employee = Depends(get_current_user), ) -> Employee: """取得當前管理員使用者""" if not current_user.is_admin: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail={"code": "AUTH003", "message": "權限不足,需要管理員權限"}, ) return current_user def get_current_hr( current_user: Employee = Depends(get_current_user), ) -> Employee: """取得當前人資使用者""" if not current_user.is_hr and not current_user.is_admin: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail={"code": "AUTH003", "message": "權限不足,需要人資權限"}, ) return current_user