35 lines
1.3 KiB
Python
35 lines
1.3 KiB
Python
"""Look widget API keys up by a SHA-256 of the key
|
|
|
|
Checking a key used to bcrypt it against every active widget app, about
|
|
100ms each, on the request's event loop, so each wrong key stalled the API
|
|
in proportion to the number of apps. widget_apps.api_key_lookup holds a
|
|
SHA-256 of the key (safe for a 256-bit random secret) so a key is one
|
|
indexed lookup. Keys issued earlier stay NULL until they are next used.
|
|
|
|
Revision ID: widget_key_lookup_001
|
|
Revises: session_conversation_key_001
|
|
Create Date: 2026-10-19
|
|
"""
|
|
from typing import Sequence, Union
|
|
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = 'widget_key_lookup_001'
|
|
down_revision: Union[str, None] = 'session_conversation_key_001'
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
INDEX_NAME = 'ix_widget_apps_api_key_lookup'
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.add_column('widget_apps', sa.Column('api_key_lookup', sa.String(64), nullable=True), if_not_exists=True)
|
|
op.create_index(INDEX_NAME, 'widget_apps', ['api_key_lookup'], unique=True, if_not_exists=True)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_index(INDEX_NAME, table_name='widget_apps', if_exists=True)
|
|
op.drop_column('widget_apps', 'api_key_lookup', if_exists=True)
|