Files
KPI-management/app/api/deps.py
DonaldFang 方士碩 f810ddc2ea Initial commit: KPI Management System Backend
Features:
- FastAPI backend with JWT authentication
- MySQL database with SQLAlchemy ORM
- KPI workflow: draft → pending → approved → evaluation → completed
- Ollama LLM API integration for AI features
- Gitea API integration for version control
- Complete API endpoints for KPI, dashboard, notifications

Tables: KPI_D_* prefix naming convention

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 16:20:57 +08:00

110 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
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