feat(auth): Add optional authentication system (#22)
Some checks failed
CI / style (push) Has been cancelled
CI / build-client (push) Has been cancelled
CI / build-amd64 (push) Has been cancelled
CI / build-tester (push) Has been cancelled
CI / test (cockroachdb) (push) Has been cancelled
CI / test (mariadb) (push) Has been cancelled
CI / test (postgres) (push) Has been cancelled
CI / test (sqlite) (push) Has been cancelled
CI / build-arm64 (push) Has been cancelled
CI / build-armv7 (push) Has been cancelled
CI / publish-images (push) Has been cancelled
CI / publish-release (push) Has been cancelled
Some checks failed
CI / style (push) Has been cancelled
CI / build-client (push) Has been cancelled
CI / build-amd64 (push) Has been cancelled
CI / build-tester (push) Has been cancelled
CI / test (cockroachdb) (push) Has been cancelled
CI / test (mariadb) (push) Has been cancelled
CI / test (postgres) (push) Has been cancelled
CI / test (sqlite) (push) Has been cancelled
CI / build-arm64 (push) Has been cancelled
CI / build-armv7 (push) Has been cancelled
CI / publish-images (push) Has been cancelled
CI / publish-release (push) Has been cancelled
Backend: - Add User model with username, hashed password, role, is_active - Add passlib[bcrypt] and python-jose[cryptography] dependencies - Create auth.py with JWT utilities, password hashing, role checking - Add /auth endpoints: status, setup, login, me, users CRUD - Add role-based permission system (viewer/operator/editor/admin) - Environment: SPOOLMAN_AUTH_ENABLED, SPOOLMAN_AUTH_SECRET_KEY - Migration for user table Frontend: - Add AuthProvider context with login/logout/setup - Add LoginPage component with setup mode for first user - Add ProtectedRoute wrapper for auth-required pages - Add axios interceptor to attach JWT token to requests - Add User Management tab in Settings (admin only) - Add translation keys for auth UI When SPOOLMAN_AUTH_ENABLED=true: - Users must login to access the app - First visit shows setup page to create admin account - Role-based access control for future endpoint protection Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
"""Add user authentication table.
|
||||
|
||||
Revision ID: d4e5f6g7h8i9
|
||||
Revises: c3d4e5f6g7h8
|
||||
Create Date: 2025-01-16 01:00:00.000000
|
||||
|
||||
"""
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "d4e5f6g7h8i9"
|
||||
down_revision = "c3d4e5f6g7h8"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.create_table(
|
||||
"user",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("username", sa.String(length=64), nullable=False),
|
||||
sa.Column("hashed_password", sa.String(length=128), nullable=False),
|
||||
sa.Column(
|
||||
"role",
|
||||
sa.String(length=16),
|
||||
nullable=False,
|
||||
server_default="viewer",
|
||||
comment="Role: 'admin', 'editor', 'operator', 'viewer'.",
|
||||
),
|
||||
sa.Column("is_active", sa.Boolean(), nullable=False, server_default=sa.text("1")),
|
||||
sa.Column("created_at", sa.DateTime(), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id"),
|
||||
)
|
||||
op.create_index(op.f("ix_user_id"), "user", ["id"], unique=False)
|
||||
op.create_index(op.f("ix_user_username"), "user", ["username"], unique=True)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_index(op.f("ix_user_username"), table_name="user")
|
||||
op.drop_index(op.f("ix_user_id"), table_name="user")
|
||||
op.drop_table("user")
|
||||
Reference in New Issue
Block a user