auth: add FastAPI service — models, deps, server, routers, CLI

Steps 3–7 of the migration plan:
- models.py: Pydantic request/response types
- deps.py: shared state, JWT-based auth helpers, rate limiting
- server.py: FastAPI app with CORS + gzip
- routers/auth.py: login, logout, /api/me, reset-password, register
- routers/invites.py: GET/POST /api/invites
- routers/admin.py: user listing, suspend/unsuspend, delete, access flags, reset-password-code
- cli.py: `bincio-auth init` (creates DB + admin + JWT secret) and `bincio-auth serve`

Cookie carries a signed JWT (HS256); consumers validate locally with shared secret.
This commit is contained in:
Davide Scaini
2026-06-02 14:38:56 +02:00
parent a3a98c033d
commit ddd15cae0f
7 changed files with 647 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
"""Pydantic request/response models for bincio-auth."""
from __future__ import annotations
from pydantic import BaseModel, Field
class LoginRequest(BaseModel):
handle: str = Field(..., description="User handle")
password: str = Field(..., description="User password")
class LoginResponse(BaseModel):
ok: bool = True
handle: str
display_name: str
is_admin: bool
wiki_access: bool
activity_access: bool
class RegisterRequest(BaseModel):
code: str = Field(..., description="Invite code")
handle: str = Field(..., description="Desired username (lowercase, 130 chars)")
password: str = Field(..., description="Password (min 8 characters)")
display_name: str = Field(default="", description="Full name (optional)")
class RegisterResponse(BaseModel):
ok: bool = True
handle: str
class ResetPasswordRequest(BaseModel):
handle: str
code: str = Field(..., description="One-time reset code (24 h TTL)")
password: str = Field(..., description="New password (min 8 chars)")
class CreateInviteRequest(BaseModel):
grants_activity: bool = Field(default=False)
class GenericResponse(BaseModel):
ok: bool = True