mirror of
https://github.com/idrainformatica/PecFlow.git
synced 2026-06-16 20:55:41 +02:00
154 lines
5.0 KiB
Python
154 lines
5.0 KiB
Python
"""RLS completa su tutte le tabelle applicative + ruolo pechub_app
|
||
|
||
Revision ID: 0006
|
||
Revises: 0005
|
||
Create Date: 2026-03-19 00:00:00.000000
|
||
|
||
Aggiunge:
|
||
- ENABLE ROW LEVEL SECURITY + policy USING (tenant_id = ...) su tutte le
|
||
tabelle applicative che mancavano (attachments, send_jobs, archival_batches,
|
||
archival_dips, labels, mailbox_permissions, virtual_boxes,
|
||
notification_channels, notification_rules, notification_log, tenant_settings)
|
||
- Crea il ruolo PostgreSQL applicativo 'pechub_app' (non-superuser) con
|
||
GRANT SELECT/INSERT/UPDATE/DELETE su tutte le tabelle.
|
||
Il ruolo viene usato dalla connessione applicativa (DATABASE_URL) mentre
|
||
Alembic continua ad usare l'utente superuser (DATABASE_URL_SYNC).
|
||
|
||
Nota: la migrazione usa DO $$ BEGIN ... EXCEPTION WHEN ... END $$ per
|
||
rendere idempotente la creazione del ruolo e delle policy.
|
||
"""
|
||
|
||
from alembic import op
|
||
|
||
revision = "0006"
|
||
down_revision = "0005"
|
||
branch_labels = None
|
||
depends_on = None
|
||
|
||
# Tabelle con tenant_id che devono avere RLS (escluse quelle già gestite in 0001)
|
||
_RLS_TABLES = [
|
||
"attachments",
|
||
"send_jobs",
|
||
"archival_batches",
|
||
"archival_dips",
|
||
"labels",
|
||
"mailbox_permissions",
|
||
"virtual_boxes",
|
||
"notification_channels",
|
||
"notification_rules",
|
||
"notification_log",
|
||
"tenant_settings",
|
||
]
|
||
|
||
# Tutte le tabelle su cui pechub_app ha SELECT/INSERT/UPDATE/DELETE
|
||
_ALL_APP_TABLES = [
|
||
"tenants",
|
||
"users",
|
||
"refresh_tokens",
|
||
"mailboxes",
|
||
"messages",
|
||
"attachments",
|
||
"send_jobs",
|
||
"archival_batches",
|
||
"archival_batch_messages",
|
||
"archival_dips",
|
||
"labels",
|
||
"message_labels",
|
||
"mailbox_permissions",
|
||
"virtual_boxes",
|
||
"virtual_box_rules",
|
||
"virtual_box_assignments",
|
||
"virtual_box_mailboxes",
|
||
"notification_channels",
|
||
"notification_rules",
|
||
"notification_log",
|
||
"audit_log",
|
||
"tenant_settings",
|
||
]
|
||
|
||
|
||
def upgrade() -> None:
|
||
# ── 1. Abilita RLS + policy su tabelle mancanti ───────────────────────────
|
||
for table in _RLS_TABLES:
|
||
op.execute(f"ALTER TABLE {table} ENABLE ROW LEVEL SECURITY")
|
||
# Politica idempotente: elimina la policy se esiste e la ricrea
|
||
op.execute(
|
||
f"""
|
||
DO $$
|
||
BEGIN
|
||
-- Elimina policy esistente (se presente da un run precedente)
|
||
DROP POLICY IF EXISTS {table}_tenant_isolation ON {table};
|
||
-- Crea la nuova policy
|
||
CREATE POLICY {table}_tenant_isolation ON {table}
|
||
USING (
|
||
tenant_id = NULLIF(
|
||
current_setting('app.current_tenant_id', TRUE), ''
|
||
)::UUID
|
||
);
|
||
END
|
||
$$;
|
||
"""
|
||
)
|
||
|
||
# ── 2. Crea ruolo applicativo pechub_app (non-superuser) ──────────────────
|
||
op.execute(
|
||
"""
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (
|
||
SELECT 1 FROM pg_roles WHERE rolname = 'pechub_app'
|
||
) THEN
|
||
CREATE USER pechub_app WITH PASSWORD 'pechub_app_password'
|
||
NOSUPERUSER NOCREATEDB NOCREATEROLE;
|
||
RAISE NOTICE 'Ruolo pechub_app creato';
|
||
ELSE
|
||
RAISE NOTICE 'Ruolo pechub_app già esistente – skip';
|
||
END IF;
|
||
END
|
||
$$;
|
||
"""
|
||
)
|
||
|
||
# ── 3. Permessi al ruolo applicativo ──────────────────────────────────────
|
||
op.execute("GRANT CONNECT ON DATABASE pechub TO pechub_app")
|
||
op.execute("GRANT USAGE ON SCHEMA public TO pechub_app")
|
||
|
||
for table in _ALL_APP_TABLES:
|
||
op.execute(
|
||
f"GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE {table} TO pechub_app"
|
||
)
|
||
|
||
# Sequenze (per BIGSERIAL come audit_log.id)
|
||
op.execute("GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO pechub_app")
|
||
|
||
# Default privileges: le tabelle create nelle migrazioni future ricevono
|
||
# automaticamente i permessi per pechub_app
|
||
op.execute(
|
||
"""
|
||
ALTER DEFAULT PRIVILEGES FOR ROLE pechub IN SCHEMA public
|
||
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO pechub_app;
|
||
"""
|
||
)
|
||
op.execute(
|
||
"""
|
||
ALTER DEFAULT PRIVILEGES FOR ROLE pechub IN SCHEMA public
|
||
GRANT USAGE, SELECT ON SEQUENCES TO pechub_app;
|
||
"""
|
||
)
|
||
|
||
|
||
def downgrade() -> None:
|
||
# Rimuovi policy e disabilita RLS
|
||
for table in _RLS_TABLES:
|
||
op.execute(
|
||
f"DROP POLICY IF EXISTS {table}_tenant_isolation ON {table}"
|
||
)
|
||
op.execute(f"ALTER TABLE {table} DISABLE ROW LEVEL SECURITY")
|
||
|
||
# Revoca permessi e rimuovi ruolo
|
||
op.execute("REVOKE ALL ON ALL TABLES IN SCHEMA public FROM pechub_app")
|
||
op.execute("REVOKE ALL ON ALL SEQUENCES IN SCHEMA public FROM pechub_app")
|
||
op.execute("REVOKE USAGE ON SCHEMA public FROM pechub_app")
|
||
op.execute("REVOKE CONNECT ON DATABASE pechub FROM pechub_app")
|
||
op.execute("DROP USER IF EXISTS pechub_app")
|