From 441909c6cfe6c8f28782b8d51c829b84b9f24649 Mon Sep 17 00:00:00 2001 From: Anders Hafreager Date: Thu, 26 Feb 2026 11:54:26 +0100 Subject: [PATCH] fix: remove unauthenticated test scaffold endpoints from backend Fixes #301 The /test POST and GET endpoints allowed unauthenticated access to the database. This removes all scaffold leftovers: - Delete backend/src/atomify_api/routers/test.py - Remove test router import and include_router from main.py - Remove test_router export from routers/__init__.py - Remove TestRecord import from db/database.py - Remove TestRecord import from migrations/env.py - Delete the initial_test_schema migration (test_records table only) --- backend/migrations/env.py | 5 -- ...2_1017_2da813b175f0_initial_test_schema.py | 37 ----------- backend/src/atomify_api/db/database.py | 4 -- backend/src/atomify_api/main.py | 2 - backend/src/atomify_api/routers/__init__.py | 3 +- backend/src/atomify_api/routers/test.py | 62 ------------------- 6 files changed, 1 insertion(+), 112 deletions(-) delete mode 100644 backend/migrations/versions/20251222_1017_2da813b175f0_initial_test_schema.py delete mode 100644 backend/src/atomify_api/routers/test.py diff --git a/backend/migrations/env.py b/backend/migrations/env.py index 78fb0b23..ee793f5d 100644 --- a/backend/migrations/env.py +++ b/backend/migrations/env.py @@ -11,10 +11,6 @@ from atomify_api.config import get_settings -# Import models to register them with SQLModel metadata -# Note: Add model imports here as they are defined -from atomify_api.routers.test import TestRecord # noqa: F401 - # Alembic Config object config = context.config @@ -84,4 +80,3 @@ def run_migrations_online() -> None: run_migrations_offline() else: run_migrations_online() - diff --git a/backend/migrations/versions/20251222_1017_2da813b175f0_initial_test_schema.py b/backend/migrations/versions/20251222_1017_2da813b175f0_initial_test_schema.py deleted file mode 100644 index f5642e19..00000000 --- a/backend/migrations/versions/20251222_1017_2da813b175f0_initial_test_schema.py +++ /dev/null @@ -1,37 +0,0 @@ -"""initial_test_schema - -Revision ID: 2da813b175f0 -Revises: -Create Date: 2025-12-22 10:17:08.947413 -""" - -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa -import sqlmodel - - -# revision identifiers, used by Alembic. -revision: str = '2da813b175f0' -down_revision: Union[str, None] = None -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('test_records', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('message', sqlmodel.sql.sqltypes.AutoString(), nullable=False), - sa.Column('created_at', sa.DateTime(), nullable=False), - sa.PrimaryKeyConstraint('id') - ) - # ### end Alembic commands ### - - -def downgrade() -> None: - # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('test_records') - # ### end Alembic commands ### - diff --git a/backend/src/atomify_api/db/database.py b/backend/src/atomify_api/db/database.py index 4f944b3d..6afac1bd 100644 --- a/backend/src/atomify_api/db/database.py +++ b/backend/src/atomify_api/db/database.py @@ -56,9 +56,6 @@ async def init_db() -> None: Note: In production, use Alembic migrations instead. """ - # Import models to register them with SQLModel metadata - from atomify_api.routers.test import TestRecord # noqa: F401 - engine = get_engine() async with engine.begin() as conn: await conn.run_sync(SQLModel.metadata.create_all) @@ -74,4 +71,3 @@ async def get_session() -> AsyncGenerator[AsyncSession, None]: except Exception: await session.rollback() raise - diff --git a/backend/src/atomify_api/main.py b/backend/src/atomify_api/main.py index 010f4659..4069eaf5 100644 --- a/backend/src/atomify_api/main.py +++ b/backend/src/atomify_api/main.py @@ -9,7 +9,6 @@ from atomify_api.config import get_settings from atomify_api.db.database import init_db from atomify_api.routers.health import router as health_router -from atomify_api.routers.test import router as test_router from atomify_api.storage.gcs import get_gcs_client @@ -45,7 +44,6 @@ def create_app() -> FastAPI: # Include routers app.include_router(health_router) - app.include_router(test_router) return app diff --git a/backend/src/atomify_api/routers/__init__.py b/backend/src/atomify_api/routers/__init__.py index f3150624..1cf68f3a 100644 --- a/backend/src/atomify_api/routers/__init__.py +++ b/backend/src/atomify_api/routers/__init__.py @@ -1,6 +1,5 @@ """API routers for the Atomify backend.""" from atomify_api.routers.health import router as health_router -from atomify_api.routers.test import router as test_router -__all__ = ["health_router", "test_router"] +__all__ = ["health_router"] diff --git a/backend/src/atomify_api/routers/test.py b/backend/src/atomify_api/routers/test.py deleted file mode 100644 index b4ea33ca..00000000 --- a/backend/src/atomify_api/routers/test.py +++ /dev/null @@ -1,62 +0,0 @@ -"""Simple test endpoint to verify database connectivity.""" - -from collections.abc import Sequence -from datetime import UTC, datetime -from typing import Annotated - -from fastapi import APIRouter, Depends -from pydantic import BaseModel -from sqlalchemy.ext.asyncio import AsyncSession -from sqlmodel import Field, SQLModel, col, select - -from atomify_api.db.database import get_session - - -# Simple test model -class TestRecord(SQLModel, table=True): - """Simple test record for database verification.""" - - __tablename__ = "test_records" - - id: int | None = Field(default=None, primary_key=True) - message: str - created_at: datetime = Field(default_factory=lambda: datetime.now(UTC)) - - -class TestInput(BaseModel): - """Input for test endpoint.""" - - message: str - - -class TestOutput(BaseModel): - """Output from test endpoint.""" - - id: int - message: str - created_at: datetime - - -router = APIRouter(tags=["test"]) - - -@router.post("/test", response_model=TestOutput) -async def create_test_record( - data: TestInput, - session: Annotated[AsyncSession, Depends(get_session)], -) -> TestRecord: - """Store a test record in the database.""" - record = TestRecord(message=data.message) - session.add(record) - await session.flush() - await session.refresh(record) - return record - - -@router.get("/test", response_model=list[TestOutput]) -async def get_test_records( - session: Annotated[AsyncSession, Depends(get_session)], -) -> Sequence[TestRecord]: - """Retrieve all test records from the database.""" - result = await session.execute(select(TestRecord).order_by(col(TestRecord.id).desc())) - return result.scalars().all()