Files
trustos/backend/app/api/routes/auth.py
drjones 463dff883b feat: initial TrustOS platform scaffold
- FastAPI backend: auth, findings, dashboard, attack paths, footprint, AI translator, risk calculator, PDF report generator
- Next.js frontend: Vault dashboard, login, findings table, finding detail with AI coach, digital footprint, reports
- PostgreSQL data model: tenants, users, assets, findings, risk scores, audit reports, attack paths
- Docker Compose + Dockerfiles for all services
- Demo seed data: Acme Corp with 6 findings and 90-day risk score history
- AI Risk Translator (OpenAI/Anthropic) with plain-English business impact
- Role-based access: executive / it_admin / trustos_admin
- Scope-lock engine: authorization required before any assessment

Stage 1-8 complete: Phase 1 Vault Audit product ready
2026-07-05 09:46:08 +00:00

38 lines
1.7 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from datetime import datetime
from app.db.session import get_db
from app.models.models import User
from app.schemas.schemas import LoginRequest, TokenResponse, UserMe
from app.core.security import verify_password, create_access_token, get_current_user_payload
router = APIRouter(prefix="/auth", tags=["auth"])
@router.post("/login", response_model=TokenResponse)
async def login(body: LoginRequest, db: AsyncSession = Depends(get_db)):
result = await db.execute(select(User).where(User.email == body.email, User.is_active == True))
user: User | None = result.scalar_one_or_none()
if not user or not verify_password(body.password, user.hashed_password):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials")
user.last_login = datetime.utcnow()
await db.commit()
token = create_access_token({"sub": user.id, "role": user.role.value, "tenant_id": user.tenant_id})
return TokenResponse(
access_token=token,
role=user.role.value,
tenant_id=user.tenant_id,
full_name=user.full_name
)
@router.get("/me", response_model=UserMe)
async def get_me(payload: dict = Depends(get_current_user_payload), db: AsyncSession = Depends(get_db)):
result = await db.execute(select(User).where(User.id == payload["sub"]))
user: User | None = result.scalar_one_or_none()
if not user:
raise HTTPException(status_code=404, detail="User not found")
return UserMe(id=user.id, email=user.email, full_name=user.full_name, role=user.role, tenant_id=user.tenant_id)