Add Fleet control plane and split manage.sh deploy menu.
Strategy nodes gain fleet token APIs; control/ app for local ops; manage.sh offers strategy vs control one-click deploy. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,9 +11,14 @@ from pydantic import BaseModel, Field
|
||||
from ..config import Settings, get_settings
|
||||
from ..credentials import get_credentials, update_credentials, upsert_env_file
|
||||
from .auth import LoginRequest, LoginResponse, issue_token, require_user
|
||||
from .fleet import consume_login_ticket
|
||||
|
||||
router = APIRouter(prefix="/api/auth", tags=["auth"])
|
||||
|
||||
|
||||
class FleetExchangeRequest(BaseModel):
|
||||
ticket: str = Field(min_length=8, max_length=256)
|
||||
|
||||
_login_hits: dict[str, list[float]] = defaultdict(list)
|
||||
|
||||
|
||||
@@ -45,6 +50,23 @@ def _rate_limit_login(ip: str, settings: Settings) -> None:
|
||||
)
|
||||
|
||||
|
||||
@router.post("/fleet-exchange", response_model=LoginResponse)
|
||||
async def fleet_exchange(
|
||||
body: FleetExchangeRequest,
|
||||
settings: Annotated[Settings, Depends(get_settings)],
|
||||
) -> LoginResponse:
|
||||
"""中控签发的一次性 ticket 兑换为普通登录会话(免密)。"""
|
||||
username = consume_login_ticket(body.ticket)
|
||||
token, ttl = issue_token(username, settings)
|
||||
return LoginResponse(
|
||||
token=token,
|
||||
username=username,
|
||||
expires_in=ttl,
|
||||
env_name=settings.env_name,
|
||||
mode=settings.mode,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/login", response_model=LoginResponse)
|
||||
async def login(
|
||||
body: LoginRequest,
|
||||
|
||||
Reference in New Issue
Block a user