diff --git a/services/comms/kustomization.yaml b/services/comms/kustomization.yaml index f1e0c80..6947617 100644 --- a/services/comms/kustomization.yaml +++ b/services/comms/kustomization.yaml @@ -15,6 +15,7 @@ resources: - mas-db-ensure-rbac.yaml - mas-db-ensure-job.yaml - comms-secrets-ensure-job.yaml + - synapse-user-seed-job.yaml - mas-deployment.yaml - element-rendered.yaml - livekit-config.yaml diff --git a/services/comms/synapse-user-seed-job.yaml b/services/comms/synapse-user-seed-job.yaml new file mode 100644 index 0000000..ea0dc49 --- /dev/null +++ b/services/comms/synapse-user-seed-job.yaml @@ -0,0 +1,112 @@ +# services/comms/synapse-user-seed-job.yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: synapse-user-seed-1 + namespace: comms +spec: + backoffLimit: 1 + ttlSecondsAfterFinished: 3600 + template: + spec: + restartPolicy: Never + containers: + - name: seed + image: python:3.11-slim + env: + - name: PGHOST + value: postgres-service.postgres.svc.cluster.local + - name: PGPORT + value: "5432" + - name: PGDATABASE + value: synapse + - name: PGUSER + value: synapse + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: synapse-db + key: POSTGRES_PASSWORD + - name: SEEDER_USER + value: othrys-seeder + - name: SEEDER_PASS + valueFrom: + secretKeyRef: + name: atlasbot-credentials-runtime + key: seeder-password + - name: BOT_USER + value: atlasbot + - name: BOT_PASS + valueFrom: + secretKeyRef: + name: atlasbot-credentials-runtime + key: bot-password + command: + - /bin/sh + - -c + - | + set -euo pipefail + pip install --no-cache-dir psycopg2-binary bcrypt >/dev/null + python - <<'PY' + import os + import time + import bcrypt + import psycopg2 + + def get_cols(cur): + cur.execute( + """ + SELECT column_name, is_nullable, column_default + FROM information_schema.columns + WHERE table_schema = 'public' AND table_name = 'users' + """ + ) + cols = {} + for name, is_nullable, default in cur.fetchall(): + cols[name] = {"nullable": is_nullable == "YES", "default": default} + return cols + + def upsert_user(cur, cols, user_id, password, admin): + now_ms = int(time.time() * 1000) + values = { + "name": user_id, + "password_hash": bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode(), + "creation_ts": now_ms, + } + if "admin" in cols: + values["admin"] = admin + if "deactivated" in cols: + values["deactivated"] = False + if "shadow_banned" in cols: + values["shadow_banned"] = False + if "is_guest" in cols: + values["is_guest"] = False + + columns = list(values.keys()) + placeholders = ", ".join(["%s"] * len(columns)) + updates = ", ".join([f"{col}=EXCLUDED.{col}" for col in columns if col != "name"]) + query = f"INSERT INTO users ({', '.join(columns)}) VALUES ({placeholders}) ON CONFLICT (name) DO UPDATE SET {updates};" + cur.execute(query, [values[c] for c in columns]) + + seeder_user = os.environ["SEEDER_USER"] + bot_user = os.environ["BOT_USER"] + server = "live.bstein.dev" + seeder_id = f"@{seeder_user}:{server}" + bot_id = f"@{bot_user}:{server}" + + conn = psycopg2.connect( + host=os.environ["PGHOST"], + port=int(os.environ["PGPORT"]), + dbname=os.environ["PGDATABASE"], + user=os.environ["PGUSER"], + password=os.environ["PGPASSWORD"], + ) + try: + with conn: + with conn.cursor() as cur: + cols = get_cols(cur) + upsert_user(cur, cols, seeder_id, os.environ["SEEDER_PASS"], True) + upsert_user(cur, cols, bot_id, os.environ["BOT_PASS"], False) + finally: + conn.close() + PY