feat: Add role-based API tokens for Claudia Docs
- Add api_tokens table with role-based access (researcher, developer, viewer)
- Add POST /auth/token/generate endpoint for creating tokens
- Add GET /auth/tokens endpoint for listing user's tokens
- Add DELETE /auth/tokens/{token_id} endpoint for revoking tokens
- Add agent_type field to documents (research, development, general)
- Implement role-based access control for documents:
- researcher: access to research and general documents
- developer: access to development and general documents
- viewer: read-only access
- Update document model and schemas with agent_type field
- Add comprehensive tests for API token functionality
- All existing tests pass (73 total)
This commit is contained in:
54
alembic/versions/002_api_tokens.py
Normal file
54
alembic/versions/002_api_tokens.py
Normal file
@@ -0,0 +1,54 @@
|
||||
"""Add api_tokens table and agent_type column
|
||||
|
||||
Revision ID: 002
|
||||
Revises: 001
|
||||
Create Date: 2026-03-31
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
revision: str = '002'
|
||||
down_revision: Union[str, None] = '001'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# Add agent_type column to documents table
|
||||
op.add_column('documents', sa.Column('agent_type', sa.String(20), sa.TEXT(), nullable=True))
|
||||
|
||||
# Set default value for existing documents
|
||||
op.execute("UPDATE documents SET agent_type = 'general' WHERE agent_type IS NULL")
|
||||
|
||||
# Make the column NOT NULL after setting defaults
|
||||
op.alter_column('documents', 'agent_type', nullable=False)
|
||||
|
||||
# Add CHECK constraint for agent_type
|
||||
op.execute("""
|
||||
CREATE INDEX IF NOT EXISTS idx_documents_agent_type ON documents(agent_type)
|
||||
""")
|
||||
|
||||
# Create api_tokens table
|
||||
op.execute("""
|
||||
CREATE TABLE IF NOT EXISTS api_tokens (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
token_hash TEXT NOT NULL,
|
||||
role TEXT NOT NULL CHECK (role IN ('researcher', 'developer', 'viewer')),
|
||||
agent_id TEXT NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT (datetime('now')),
|
||||
last_used_at TIMESTAMP NULL
|
||||
)
|
||||
""")
|
||||
|
||||
# Create index for api_tokens
|
||||
op.execute("CREATE INDEX IF NOT EXISTS idx_api_tokens_agent ON api_tokens(agent_id)")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_table('api_tokens')
|
||||
op.drop_column('documents', 'agent_type')
|
||||
Reference in New Issue
Block a user