#!/opt/pw/bin/python """bookstack_token.py — the admin logs in to BookStack and creates an API token on his own account page (B4). Env PW = the admin password. Token id + secret go to /root/work/bs-token (0600), never printed.""" import os, re from playwright.sync_api import sync_playwright with sync_playwright() as p: b = p.chromium.launch(executable_path="/usr/bin/chromium", args=["--no-sandbox"]) pg = b.new_context(locale="hu-HU", ignore_https_errors=True, viewport={"width": 1366, "height": 768}).new_page() pg.goto("https://wiki.tester4.test/login", wait_until="networkidle") pg.fill("input[name=email]", "admin@admin.com"); pg.fill("input[name=password]", os.environ["PW"]) pg.press("input[name=password]", "Enter"); pg.wait_for_load_state("networkidle") print("after login:", pg.url) for u in ("https://wiki.tester4.test/my-account/auth", "https://wiki.tester4.test/users/1"): pg.goto(u, wait_until="networkidle") print(u, "token links:", pg.locator("a").evaluate_all("els => els.map(e => e.getAttribute('href')).filter(h => h && /token/i.test(h))")) link = pg.locator("a[href*='token'][href*='create']") if link.count(): break print("create-token link found:", link.count()) link.first.click(); pg.wait_for_load_state("networkidle") pg.fill("input[name=name]", "csaladi-feltoltes") pg.locator("main form button, #content form button").last.click(); pg.wait_for_load_state("networkidle") vals = [v for v in pg.locator("input[readonly]").evaluate_all("els => els.map(e => e.value)") if v] print("readonly values on the token page:", len(vals)) fd = os.open("/root/work/bs-token", os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600) os.write(fd, ("\n".join(vals[:2])).encode()); os.close(fd) b.close()