from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel from datetime import datetime, timedelta from app.api.auth import get_current_user from app.schemas.auth import CurrentUser from app.services.temp_ssh_password_service import temp_ssh_password_manager from app.config import settings import os router = APIRouter() class SshVerifyRequest(BaseModel): """SSH 비밀번호 검증 요청""" username: str password: str @router.post("/credentials") async def get_ssh_credentials(current_user: CurrentUser = Depends(get_current_user)): """ JWT 토큰으로 임시 SSH 자격증명 발급 Returns: SSH 연결 정보 및 임시 비밀번호 """ # 1. 정적 자격증명 확인 (개발 환경 또는 정적 비밀번호 사용 시) if settings.SSH_PASSWORD: ssh_host = settings.SSH_HOST or "api.mouse84.com" ssh_port = settings.SSH_PORT ssh_username = settings.SSH_USERNAME or current_user.username # 만료 시간 (24시간) expires_at = datetime.utcnow() + timedelta(hours=24) return { "ssh_host": ssh_host, "ssh_port": ssh_port, "ssh_username": ssh_username, "ssh_password": settings.SSH_PASSWORD, "expires_at": expires_at.isoformat(), "expires_in_seconds": 86400 } # 2. 임시 비밀번호 생성 (기본 동작) # .env 설정을 우선 사용 (username이 지정된 경우 해당 계정으로 임시 비밀번호 생성) target_username = settings.SSH_USERNAME or current_user.username # 임시 비밀번호 생성 (1시간 유효) temp_password = temp_ssh_password_manager.generate_password( username=target_username, validity_hours=1 ) # SSH 서버 정보 (설정값 우선) ssh_host = settings.SSH_HOST or "api.mouse84.com" ssh_port = settings.SSH_PORT or 54054 # 만료 시간 계산 expires_at = datetime.utcnow() + timedelta(hours=1) return { "ssh_host": ssh_host, "ssh_port": ssh_port, "ssh_username": target_username, "ssh_password": temp_password, "expires_at": expires_at.isoformat(), "expires_in_seconds": 3600 } @router.post("/verify") async def verify_ssh_password(request: SshVerifyRequest): """ 임시 SSH 비밀번호 검증 (PAM 인증용) Args: request: 사용자명과 비밀번호 Returns: 200: 비밀번호 유효 401: 비밀번호 무효 """ is_valid = temp_ssh_password_manager.verify_password( username=request.username, password=request.password ) if is_valid: return {"valid": True, "message": "Password verified"} else: raise HTTPException(status_code=401, detail="Invalid password")