Files
Gan, Jimmy 394a1aa367 security: harden dashboard (SSH keys, auth, uploads, CORS, non-root)
Remove SSH private keys from git, add SECRET_KEY validation, move WS
auth from query string to first message, add session limits/idle timeout,
PBKDF2 Fernet key, refresh token rotation, TOTP replay protection,
file upload size limit + filename sanitization, symlink safety check,
restrict CORS methods, IP-gate OpenClaw token, run container as non-root,
rate-limit refresh/passkey endpoints, sanitize Gitea path params.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-26 17:22:25 +08:00

25 lines
903 B
Python

import re
import httpx
from fastapi import APIRouter, HTTPException
from config import GITEA_URL, GITEA_TOKEN
router = APIRouter()
HEADERS = {"Authorization": f"token {GITEA_TOKEN}"} if GITEA_TOKEN else {}
_SAFE_NAME = re.compile(r'^[a-zA-Z0-9._-]+$')
@router.get("/repos")
async def list_repos():
async with httpx.AsyncClient() as c:
r = await c.get(f"{GITEA_URL}/api/v1/repos/search", headers=HEADERS, params={"limit": 50})
return r.json()
@router.get("/repos/{owner}/{repo}/commits")
async def list_commits(owner: str, repo: str, page: int = 1):
if not _SAFE_NAME.match(owner) or not _SAFE_NAME.match(repo):
raise HTTPException(status_code=400, detail="Invalid owner or repo name")
async with httpx.AsyncClient() as c:
r = await c.get(f"{GITEA_URL}/api/v1/repos/{owner}/{repo}/commits", headers=HEADERS, params={"page": page})
return r.json()