- Remove role field from UserCreate schema, hardcode 'engineer' at registration
- Escape all user content in HTML export with html.escape() (XSS fix)
- Add field_validator to reject default SECRET_KEY when DEBUG=False
- Add CHECK constraint on users.role ('engineer'|'viewer') + migration 011
- Fix test_admin fixture to properly grant is_super_admin via ORM
- Fix circular FK (users↔invite_codes) in test DB setup with DROP SCHEMA CASCADE
- Add 5 new security tests (role validation + XSS prevention)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
35 lines
879 B
Python
35 lines
879 B
Python
"""add role check constraint to users
|
|
|
|
Revision ID: 011
|
|
Revises: 010
|
|
Create Date: 2026-02-05
|
|
|
|
"""
|
|
from typing import Sequence, Union
|
|
|
|
from alembic import op
|
|
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = '011'
|
|
down_revision: Union[str, None] = '010'
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
# Normalize any remaining non-standard role values to 'engineer'
|
|
# (migration 010 already converted 'admin' -> 'engineer', this is defense-in-depth)
|
|
op.execute(
|
|
"UPDATE users SET role = 'engineer' WHERE role NOT IN ('engineer', 'viewer')"
|
|
)
|
|
op.create_check_constraint(
|
|
'ck_users_role_enum',
|
|
'users',
|
|
"role IN ('engineer', 'viewer')"
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_constraint('ck_users_role_enum', 'users', type_='check')
|