67 lines
2.2 KiB
Python
67 lines
2.2 KiB
Python
"""Disable RLS on login-related tables (roles, permissions).
|
|
|
|
⚠️ KI / AGENT HINWEIS — BITTE VOR ÄNDERUNGEN LESEN ⚠️
|
|
|
|
Migration 0108 hat RLS auf alle Tabellen mit tenant_id aktiviert, darunter auch
|
|
`roles` und `permissions`. Diese Tabellen werden vom Login-Flow gelesen um die
|
|
Benutzerrolle zu bestimmen. Mit RLS auf diesen Tabellen und keinem tenant_id
|
|
Kontext beim Login → Query gibt nichts zurück → Login schlägt fehl mit 401.
|
|
|
|
Diese Tabellen MÜSSEN ohne RLS bleiben, genau wie users, sessions, tenants,
|
|
user_tenants, password_reset_tokens (siehe 0108 LOGIN_TABLES).
|
|
|
|
Lektion: RLS darf NICHT auf Tabellen aktiviert werden die vom Login-Flow
|
|
gelesen werden, wenn der Login-Flow noch keinen tenant_id Kontext hat.
|
|
|
|
Revision ID: 0109
|
|
Revises: 0108
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from alembic import op
|
|
|
|
revision = "0109"
|
|
down_revision = "0108"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
# ⚠️ LOGIN-RELATED TABLES — KEIN RLS! Diese Tabellen werden vom Login-Flow
|
|
# gelesen bevor ein tenant_id Kontext existiert. RLS blockiert den Login.
|
|
# Siehe auch 0108 LOGIN_TABLES und 0085 AUTH_TABLES.
|
|
LOGIN_RELATED_TABLES = [
|
|
"roles",
|
|
"permissions",
|
|
]
|
|
|
|
|
|
def _exec(sql: str) -> None:
|
|
op.execute(sql)
|
|
|
|
|
|
def upgrade() -> None:
|
|
# Disable RLS on login-related tables
|
|
for table in LOGIN_RELATED_TABLES:
|
|
_exec(
|
|
f"DO $$ BEGIN IF EXISTS (SELECT 1 FROM information_schema.tables "
|
|
f"WHERE table_schema = 'public' AND table_name = '{table}') THEN "
|
|
f"DROP POLICY IF EXISTS tenant_isolation ON public.{table}; "
|
|
f"DROP POLICY IF EXISTS {table}_tenant_isolation ON public.{table}; "
|
|
f"ALTER TABLE public.{table} DISABLE ROW LEVEL SECURITY; "
|
|
f"END IF; END $$"
|
|
)
|
|
|
|
# Ensure crm_auth can read roles and permissions (needed for login flow)
|
|
for table in LOGIN_RELATED_TABLES:
|
|
_exec(
|
|
f"DO $$ BEGIN IF EXISTS (SELECT 1 FROM information_schema.tables "
|
|
f"WHERE table_schema = 'public' AND table_name = '{table}') THEN "
|
|
f"GRANT SELECT ON public.{table} TO crm_auth; "
|
|
f"END IF; END $$"
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
pass
|