Files
OSIT-AE-API-FastAPI/app/routers/registry.py
Scott Idem 687472f4e3 feat(user): V3 action endpoints + auth bug fixes (19/19 + 22/22 tests)
New router: /v3/action/user/ (api_v3_actions_user.py)
  - POST /authenticate  — credentials in body (not query params; security fix)
  - POST /verify_password
  - POST /{user_id}/change_password  — optional current-password verification
  - GET  /{user_id}/new_auth_key
  - GET  /{user_id}/email_auth_key_url
  Registered in registry.py under /v3/action/user with V3 AccountContext auth.

Bug fixes (from audit in previous session):
  - user.py: fix broken @router.get decorator (authenticate was unreachable)
  - user.py + user_methods.py: fix AttributeError id_random → id (Vision ID)
  - user_models.py: add fields_to_exclude_from_db to User_New_Base; narrow
    collision prevention to self-reference IDs only
  - user_models.py: pre-inject hashed password in root_validator(pre=True) so
    exclude_unset=True in CRUD POST handler includes it (was writing NULL)
  - api_crud_v3.py: move sanitize_payload + account_id injection to after
    model validation (fixes FK integer collision with Vision ID constraints)

Docs: GUIDE__AE_API_V3_for_Frontend.md — new Section 7 with full migration
  table (legacy → V3), request/response docs for all 5 action endpoints,
  and V3 CRUD search equivalents for the 3 lookup routes.

Tests: tests/e2e/test_e2e_v3_user_action_routes.py — 19 tests, 19/19 pass.
  Legacy tests/e2e/test_e2e_v3_user_auth_routes.py — 22/22 still pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 21:54:09 -04:00

75 lines
5.7 KiB
Python

from fastapi import FastAPI, Depends
from app.routers.dependencies_v3 import DeprecationParams
from app.routers import (
ae_obj, aether_cfg, api_crud_v3, api, health, importing,
data_store,
event_badge_importing,
event_importing,
api_v3_actions_hosted_file, api_v3_actions_event_file, api_v3_actions_event_exhibit, api_v3_actions_e_zoom, api_v3_actions_e_novi_mailman, api_v3_actions_user, lookup_v3,
user,
util_email, websockets_v3, e_confex, e_cvent, e_impexium, e_stripe
)
def setup_routers(app: FastAPI):
"""
Registers all application routers with their respective prefixes and tags.
"""
app.include_router(health.router, tags=['Root'])
app.include_router(ae_obj.router, prefix='/ae_obj', tags=['AE Object'])
app.include_router(aether_cfg.router, tags=['Aether Config'])
# app.include_router(api_crud.router, prefix='/crud', tags=['CRUD v1.2 (Legacy)'], dependencies=[Depends(DeprecationParams)])
# app.include_router(api_crud_v2.router, prefix='/v2/crud', tags=['CRUD v2.5'], dependencies=[Depends(DeprecationParams)])
app.include_router(api_crud_v3.router, prefix='/v3/crud', tags=['CRUD v3'])
app.include_router(api.router, prefix='/api', tags=['API'])
# app.include_router(flask_cfg.router, prefix='/flask_cfg', tags=['Flask CFG'], dependencies=[Depends(DeprecationParams)])
app.include_router(importing.router, prefix='/importing', tags=['Importing'], dependencies=[Depends(DeprecationParams)])
# app.include_router(sql.router, tags=['SQL']) # LEGACY (disabled) - raw SQL select endpoint, testing only
# app.include_router(account.router, tags=['Account'], dependencies=[Depends(DeprecationParams)])
app.include_router(data_store.router, tags=['Data Store'])
# app.include_router(event.router, tags=['Event'], dependencies=[Depends(DeprecationParams)])
# app.include_router(event_badge.router, tags=['Event Badge'], dependencies=[Depends(DeprecationParams)])
app.include_router(event_badge_importing.router, tags=['Event Badge Importing'])
# app.include_router(event_badge_template.router, tags=['Event Badge Template'], dependencies=[Depends(DeprecationParams)])
# app.include_router(event_device.router, tags=['Event Device'], dependencies=[Depends(DeprecationParams)])
# app.include_router(event_exhibit.router, tags=['Event Exhibit'], dependencies=[Depends(DeprecationParams)])
# app.include_router(event_exhibit_tracking.router, tags=['Event Exhibit Tracking'])
# app.include_router(event_file.router, tags=['Event File'])
app.include_router(event_importing.router, tags=['Event Importing'])
# app.include_router(event_location.router, tags=['Event Location'], dependencies=[Depends(DeprecationParams)])
# app.include_router(event_presentation.router, tags=['Event Presentation'], dependencies=[Depends(DeprecationParams)])
# app.include_router(event_presenter.router, prefix='/event/presenter', tags=['Event Presenter'], dependencies=[Depends(DeprecationParams)])
# app.include_router(event_session.router, tags=['Event Session'], dependencies=[Depends(DeprecationParams)])
# app.include_router(hosted_file.router, prefix='/hosted_file', tags=['Hosted File'])
app.include_router(api_v3_actions_hosted_file.router, prefix='/v3/action/hosted_file', tags=['Hosted File (V3 Actions)'])
app.include_router(api_v3_actions_event_file.router, prefix='/v3/action/event_file', tags=['Event File (V3 Actions)'])
app.include_router(api_v3_actions_event_exhibit.router, prefix='/v3/action/event_exhibit', tags=['Event Exhibit (V3 Actions)'])
app.include_router(api_v3_actions_e_zoom.router, prefix='/v3/action/e_zoom', tags=['Zoom Events (V3 Actions)'])
app.include_router(api_v3_actions_e_novi_mailman.router, prefix='/v3/action/e_novi_mailman', tags=['Novi-Mailman Bridge (V3 Actions)'])
app.include_router(api_v3_actions_user.router, prefix='/v3/action/user', tags=['User (V3 Actions)'])
# app.include_router(lookup.router, prefix='/lu', tags=['Lookup']) # LEGACY (disabled) - superseded by /v3/lookup
app.include_router(lookup_v3.router, prefix='/v3/lookup', tags=['Lookup V3'])
# app.include_router(organization.router, prefix='/organization', tags=['Organization'], dependencies=[Depends(DeprecationParams)])
# app.include_router(page.router, prefix='/page', tags=['Page'], dependencies=[Depends(DeprecationParams)])
# app.include_router(person.router, tags=['Person'], dependencies=[Depends(DeprecationParams)])
# app.include_router(person_user.router, prefix='/person_user', tags=['Person User'], dependencies=[Depends(DeprecationParams)])
# app.include_router(qr.router, tags=['QR'], dependencies=[Depends(DeprecationParams)])
# app.include_router(site.router, tags=['Site'], dependencies=[Depends(DeprecationParams)])
# app.include_router(site_domain.router, tags=['Site Domain'], dependencies=[Depends(DeprecationParams)])
app.include_router(user.router, tags=['User'], dependencies=[Depends(DeprecationParams)])
app.include_router(util_email.router, tags=['Utility: Email'])
# app.include_router(websockets.router, tags=['Websockets']) # LEGACY (disabled) - superseded by Websockets V3
# app.include_router(websockets_redis.router, tags=['Websockets (Redis)']) # LEGACY (disabled) - superseded by Websockets V3
app.include_router(websockets_v3.router, prefix='/v3', tags=['Websockets V3'])
app.include_router(e_confex.router, prefix='/e/confex', tags=['External Service: Confex'])
app.include_router(e_cvent.router, prefix='/e/cvent', tags=['External Service: Cvent'])
app.include_router(e_impexium.router, prefix='/e/impexium', tags=['External Service: Impexium'])
app.include_router(e_stripe.router, prefix='/e/stripe', tags=['External Service: Stripe'])