From e28be9d78ce8a1fa320f7c50a2192c010aaef470 Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Thu, 15 Jan 2026 03:03:34 +0530 Subject: [PATCH] feat: centralize Electric SQL user credentials in configuration - Added centralized configuration for Electric SQL user credentials in env.py. - Updated migration script to utilize these credentials for creating and granting permissions to the Electric SQL user. --- surfsense_backend/alembic/env.py | 9 +++++++ .../versions/62_add_notifications_table.py | 27 +++++++++++-------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/surfsense_backend/alembic/env.py b/surfsense_backend/alembic/env.py index bd8c20356..2b82cb93a 100644 --- a/surfsense_backend/alembic/env.py +++ b/surfsense_backend/alembic/env.py @@ -25,6 +25,15 @@ database_url = os.getenv("DATABASE_URL") if database_url: config.set_main_option("sqlalchemy.url", database_url) +# Electric SQL user credentials - centralized configuration for migrations +# These are used by migrations that set up Electric SQL replication +config.set_main_option( + "electric_db_user", os.getenv("ELECTRIC_DB_USER", "electric") +) +config.set_main_option( + "electric_db_password", os.getenv("ELECTRIC_DB_PASSWORD", "electric_password") +) + # Interpret the config file for Python logging. # This line sets up loggers basically. if config.config_file_name is not None: diff --git a/surfsense_backend/alembic/versions/62_add_notifications_table.py b/surfsense_backend/alembic/versions/62_add_notifications_table.py index 36dbd7382..c831b901f 100644 --- a/surfsense_backend/alembic/versions/62_add_notifications_table.py +++ b/surfsense_backend/alembic/versions/62_add_notifications_table.py @@ -10,7 +10,12 @@ search_source_connectors, and documents tables. from collections.abc import Sequence -from alembic import op +from alembic import context, op + +# Get Electric SQL user credentials from env.py configuration +_config = context.config +ELECTRIC_DB_USER = _config.get_main_option("electric_db_user", "electric") +ELECTRIC_DB_PASSWORD = _config.get_main_option("electric_db_password", "electric_password") # revision identifiers, used by Alembic. revision: str = "62" @@ -51,11 +56,11 @@ def upgrade() -> None: # Create Electric SQL replication user if not exists op.execute( - """ + f""" DO $$ BEGIN - IF NOT EXISTS (SELECT FROM pg_user WHERE usename = 'electric') THEN - CREATE USER electric WITH REPLICATION PASSWORD 'electric_password'; + IF NOT EXISTS (SELECT FROM pg_user WHERE usename = '{ELECTRIC_DB_USER}') THEN + CREATE USER {ELECTRIC_DB_USER} WITH REPLICATION PASSWORD '{ELECTRIC_DB_PASSWORD}'; END IF; END $$; @@ -64,21 +69,21 @@ def upgrade() -> None: # Grant necessary permissions to electric user op.execute( - """ + f""" DO $$ DECLARE db_name TEXT := current_database(); BEGIN - EXECUTE format('GRANT CONNECT ON DATABASE %I TO electric', db_name); + EXECUTE format('GRANT CONNECT ON DATABASE %I TO {ELECTRIC_DB_USER}', db_name); END $$; """ ) - op.execute("GRANT USAGE ON SCHEMA public TO electric;") - op.execute("GRANT SELECT ON ALL TABLES IN SCHEMA public TO electric;") - op.execute("GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO electric;") - op.execute("ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO electric;") - op.execute("ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON SEQUENCES TO electric;") + op.execute(f"GRANT USAGE ON SCHEMA public TO {ELECTRIC_DB_USER};") + op.execute(f"GRANT SELECT ON ALL TABLES IN SCHEMA public TO {ELECTRIC_DB_USER};") + op.execute(f"GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO {ELECTRIC_DB_USER};") + op.execute(f"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO {ELECTRIC_DB_USER};") + op.execute(f"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON SEQUENCES TO {ELECTRIC_DB_USER};") # Create the publication if not exists op.execute(