Spaces:
Sleeping
Sleeping
| """ | |
| User integrations API — connect/disconnect a GitHub account (PAT, stored encrypted). | |
| Auth-required; operates on the current user only. The PAT is validated against the | |
| GitHub API, then stored ENCRYPTED (auth/crypto.py). The token is NEVER returned. | |
| """ | |
| import logging | |
| from fastapi import APIRouter, Depends, HTTPException | |
| from pydantic import BaseModel | |
| from sqlalchemy.orm import Session | |
| from auth.crypto import encrypt | |
| from auth.dependencies import get_current_user | |
| from db.database import get_db | |
| from db.models import User | |
| from integrations import github_client | |
| logger = logging.getLogger(__name__) | |
| router = APIRouter(prefix="/me/integrations", tags=["integrations"]) | |
| class GitHubTokenRequest(BaseModel): | |
| token: str | |
| def _load_user(db: Session, current_user: User) -> User: | |
| """Re-load the user on the request's DB session so writes persist.""" | |
| user = db.query(User).filter(User.id == current_user.id).first() | |
| if not user: | |
| raise HTTPException(status_code=404, detail="User not found") | |
| return user | |
| def connect_github( | |
| req: GitHubTokenRequest, | |
| current_user: User = Depends(get_current_user), | |
| db: Session = Depends(get_db), | |
| ) -> dict: | |
| token = (req.token or "").strip() | |
| if not token: | |
| raise HTTPException(status_code=400, detail="token is required") | |
| try: | |
| login = github_client.validate_token(token) | |
| except ValueError: | |
| # ponytail: never echo the token or the upstream error verbatim. | |
| raise HTTPException(status_code=400, detail="Invalid GitHub token") | |
| user = _load_user(db, current_user) | |
| user.github_token_enc = encrypt(token) # stored ENCRYPTED, never plaintext | |
| user.github_login = login | |
| db.commit() | |
| return {"connected": True, "login": login} | |
| def disconnect_github( | |
| current_user: User = Depends(get_current_user), | |
| db: Session = Depends(get_db), | |
| ) -> dict: | |
| user = _load_user(db, current_user) | |
| user.github_token_enc = None | |
| user.github_login = None | |
| db.commit() | |
| return {"connected": False} | |