Files
GitMa/backend/app/api/deps.py
panw 44921c5646 feat: complete Git Repo Manager MVP implementation
Backend (Phase 1-6):
- Pydantic schemas for request/response validation
- Service layer (SSH Key, Server, Repo, Sync)
- API routes with authentication
- FastAPI main application with lifespan management
- ORM models (SshKey, Server, Repo, SyncLog)

Frontend (Phase 7):
- Vue 3 + Element Plus + Pinia + Vue Router
- API client with Axios and interceptors
- State management stores
- All page components (Dashboard, Servers, Repos, SyncLogs, SshKeys, Settings)

Deployment (Phase 8):
- README with quick start guide
- Startup script (start.sh)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 16:30:13 +08:00

112 lines
3.1 KiB
Python

"""
FastAPI dependencies for API routes.
Provides reusable dependencies for:
- Database session management
- Authentication/authorization
"""
from typing import Generator, Optional
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from sqlalchemy.orm import Session
from app.database import get_session_factory
from app.security import verify_api_token
# HTTP Bearer token security scheme
security = HTTPBearer(auto_error=False)
def get_db_session() -> Generator[Session, None, None]:
"""
Dependency to get a database session.
Yields:
SQLAlchemy database session
Example:
@app.get("/items")
def read_items(db: Session = Depends(get_db_session)):
items = db.query(Item).all()
return items
"""
session_factory = get_session_factory()
if session_factory is None:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Database not initialized"
)
session = session_factory()
try:
yield session
finally:
session.close()
def require_auth(
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security)
) -> None:
"""
Dependency to require authentication for protected endpoints.
Args:
credentials: HTTP Bearer token credentials
Raises:
HTTPException: If authentication fails (401 Unauthorized)
Example:
@app.get("/protected")
def protected_route(auth: None = Depends(require_auth)):
return {"message": "authenticated"}
"""
if credentials is None:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Missing authentication credentials",
headers={"WWW-Authenticate": "Bearer"},
)
authorization = f"Bearer {credentials.credentials}"
if not verify_api_token(authorization):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authentication token",
headers={"WWW-Authenticate": "Bearer"},
)
# Return None to indicate successful authentication
return None
async def require_auth_optional(
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security)
) -> bool:
"""
Optional authentication dependency.
Returns True if authenticated, False otherwise.
This is useful for endpoints that have different behavior
based on authentication status but don't require it.
Args:
credentials: HTTP Bearer token credentials
Returns:
bool: True if authenticated, False otherwise
Example:
@app.get("/public")
def public_route(authenticated: bool = Depends(require_auth_optional)):
if authenticated:
return {"message": "authenticated user"}
return {"message": "anonymous user"}
"""
if credentials is None:
return False
authorization = f"Bearer {credentials.credentials}"
return verify_api_token(authorization)