fix: dashboard endpoint and SSH key Fernet key generation
- Create missing /dashboard/summary endpoint that frontend expects - Fix SSH key Fernet key generation to use proper base64 encoding (was using raw session secret slice which failed validation)
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import uuid
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy import func, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from src.auth.dependencies import get_current_user_id, get_db_session
|
||||
from src.models.git_repository import GitRepository
|
||||
from src.models.project import Project
|
||||
from src.models.ssh_key import SSHKey
|
||||
|
||||
router = APIRouter(prefix="/dashboard", tags=["dashboard"])
|
||||
|
||||
|
||||
@router.get("/summary")
|
||||
async def get_dashboard_summary(
|
||||
user_id: uuid.UUID = Depends(get_current_user_id),
|
||||
session: AsyncSession = Depends(get_db_session),
|
||||
) -> dict:
|
||||
# Count user's projects
|
||||
projects_result = await session.execute(
|
||||
select(func.count()).select_from(Project).where(Project.owner_id == user_id)
|
||||
)
|
||||
projects_count = projects_result.scalar() or 0
|
||||
|
||||
# Count user's repositories
|
||||
repos_result = await session.execute(
|
||||
select(func.count()).select_from(GitRepository).where(GitRepository.owner_id == user_id)
|
||||
)
|
||||
repos_count = repos_result.scalar() or 0
|
||||
|
||||
# Count user's SSH keys
|
||||
ssh_keys_result = await session.execute(
|
||||
select(func.count()).select_from(SSHKey).where(SSHKey.user_id == user_id)
|
||||
)
|
||||
ssh_keys_count = ssh_keys_result.scalar() or 0
|
||||
|
||||
# Get recent activity (latest 5 projects)
|
||||
recent_projects = await session.execute(
|
||||
select(Project)
|
||||
.where(Project.owner_id == user_id)
|
||||
.order_by(Project.created_at.desc())
|
||||
.limit(5)
|
||||
)
|
||||
recent_activity = [f"Created project: {p.name}" for p in recent_projects.scalars().all()]
|
||||
|
||||
return {
|
||||
"projects": projects_count,
|
||||
"repositories": repos_count,
|
||||
"sshKeys": ssh_keys_count,
|
||||
"recentActivity": recent_activity,
|
||||
}
|
||||
@@ -25,9 +25,16 @@ async def _get_user(session: AsyncSession, user_id: uuid.UUID) -> User:
|
||||
|
||||
|
||||
def _get_fernet() -> Fernet:
|
||||
"""Generate a valid Fernet key from the session secret."""
|
||||
import base64
|
||||
import hashlib
|
||||
|
||||
settings = Settings()
|
||||
key = settings.session_secret[:32].ljust(32, "=")
|
||||
return Fernet(key.encode())
|
||||
# Derive a 32-byte key from the session secret using SHA256
|
||||
key_bytes = hashlib.sha256(settings.session_secret.encode()).digest()
|
||||
# Base64 encode it for Fernet (must be 32 url-safe base64-encoded bytes)
|
||||
key = base64.urlsafe_b64encode(key_bytes)
|
||||
return Fernet(key)
|
||||
|
||||
|
||||
def generate_ssh_key_pair() -> tuple[str, str]:
|
||||
|
||||
@@ -7,6 +7,7 @@ from fastapi.staticfiles import StaticFiles
|
||||
from sqlalchemy import select, text
|
||||
|
||||
from src.api.auth import router as auth_router
|
||||
from src.api.dashboard import router as dashboard_router
|
||||
from src.api.git_repositories import router as git_repositories_router
|
||||
from src.api.projects import router as projects_router
|
||||
from src.api.ssh_keys import router as ssh_keys_router
|
||||
@@ -156,6 +157,7 @@ async def health_check():
|
||||
return {"status": "unhealthy", "database": "disconnected", "error": str(exc)}
|
||||
|
||||
app.include_router(auth_router)
|
||||
app.include_router(dashboard_router)
|
||||
app.include_router(projects_router)
|
||||
app.include_router(users_router)
|
||||
app.include_router(ssh_keys_router)
|
||||
|
||||
Reference in New Issue
Block a user