Files
4ventures-client-portal/scripts/dokploy_rls_inventory.py
2026-09-21 18:20:25 +02:00

91 lines
3.1 KiB
Python

#!/usr/bin/env python3
"""Run RLS checklist query in supabase-db; print table/RLS summary."""
from __future__ import annotations
import re
import sys
from pathlib import Path
from playwright.sync_api import sync_playwright
ROOT = Path("/Users/4ventures/4ventures-client-portal")
BPS = Path("/Users/4ventures/Projects/bps-facturacion")
SHOT = ROOT / "scripts/dokploy-shots"
BASE = "https://dokploy.4ventures.es"
OUT = ROOT / ".ops" / "rls_inventory.txt"
QUERY = r"""
SELECT c.relname AS table_name, c.relrowsecurity AS rls_enabled
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public' AND c.relkind = 'r'
ORDER BY 1;
"""
def env(key: str) -> str:
import os
v = os.environ.get(key, "").strip()
if v:
return v
p = BPS / ".env"
if not p.is_file():
return ""
for line in p.read_text(encoding="utf-8").splitlines():
if line.startswith(f"{key}="):
return line.split("=", 1)[1].strip().strip('"').strip("'")
return ""
def main() -> int:
email = env("DOKPLOY_EMAIL") or "marketing@4ventures.es"
password = env("DOKPLOY_PASSWORD")
# compact to one line for psql -c
q = " ".join(QUERY.split())
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page(viewport={"width": 1600, "height": 1200})
page.goto(BASE + "/", wait_until="domcontentloaded", timeout=90000)
page.wait_for_timeout(700)
if "/dashboard" not in page.url:
page.locator('input[type="email"], input[name="email"]').first.fill(email)
page.locator('input[type="password"]').first.fill(password)
page.locator('button[type="submit"]').first.click()
page.wait_for_url(re.compile(r"/dashboard"), timeout=90000)
page.goto(f"{BASE}/dashboard/docker", wait_until="networkidle", timeout=120000)
page.wait_for_timeout(1000)
page.locator("input[placeholder*='ilter' i], input[placeholder*='earch' i]").first.fill("supabase-db")
page.wait_for_timeout(1000)
page.get_by_role("button", name=re.compile(r"Open menu", re.I)).first.click()
page.wait_for_timeout(500)
page.get_by_text(re.compile(r"^Terminal$", re.I)).first.click()
page.wait_for_timeout(3000)
helper = page.locator("textarea.xterm-helper-textarea")
if helper.count():
helper.first.click()
cmd = f"psql -U postgres -d postgres -c \"{q}\" ; echo RLS_DONE"
page.keyboard.type(cmd, delay=2)
page.keyboard.press("Enter")
page.wait_for_timeout(6000)
page.screenshot(path=str(SHOT / "rls_term.png"), full_page=True)
text = page.evaluate(
"""() => {
const rows = document.querySelector('.xterm-rows');
return rows ? rows.innerText : '';
}"""
)
OUT.parent.mkdir(exist_ok=True)
OUT.write_text(text or "", encoding="utf-8")
print(text[-2500:] if text else "NO_TEXT", flush=True)
browser.close()
print("wrote", OUT, flush=True)
return 0
if __name__ == "__main__":
raise SystemExit(main())