From c0eb1b383b7fcdbfe73906c643c9cda27384b2e1 Mon Sep 17 00:00:00 2001 From: TSYS Group COO Date: Thu, 13 Aug 2026 18:37:20 -0500 Subject: [PATCH] feat: Gitea SSO + token generation working end-to-end MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Working flows: - Cloudron panel login (Pankow Vue UI: keyboard.type + role=button) - Gitea SSO via Cloudron OIDC (redirects, auto-consent, authenticated) - Gitea API token generation (JS-based form fill for hidden elements) - Token extraction from flash-info message (regex for 40-char hex) - Token verified via Gitea API (user=vptechops) - Token stored in Bitwarden as "vp-techops Gitea" Issues remaining: - Redmine SSO: OIDC consent completes but redirects back to login page (likely Redmine OAuth config or user sync issue) - Discourse: SSO button not found (needs different selector) - 2FA: enable button not found on Cloudron profile page (TOTP section exists but button selector needs investigation) - Gitea: stale token cleanup needed (old duplicate from failed runs) Key pattern established for Cloudron SSO across all apps: 1. cloudron_panel_login() to establish session 2. sso_login() clicks app-specific SSO button 3. OIDC handles auth automatically (session already active) 4. Redirect back to app authenticated 💘 Generated with Crush Assisted-by: Crush:glm-5.2 --- provision-agent.py | 183 ++++++++++++++++++++++++++++++--------------- 1 file changed, 124 insertions(+), 59 deletions(-) diff --git a/provision-agent.py b/provision-agent.py index 35075ac..7f7e799 100644 --- a/provision-agent.py +++ b/provision-agent.py @@ -326,24 +326,24 @@ def cloudron_panel_login(page: Page, agent: dict, bw: BitwardenHelper) -> bool: # If redirected to OIDC login page, fill that too # (Cloudron login.html and OIDC login look similar, both use #inputUsername/#inputPassword) - # Fill Cloudron login form (same selectors as invite page) + # Fill Cloudron login form (Pankow/Vue needs keyboard events, not fill()) page.wait_for_selector("#inputPassword", timeout=15000) - page.fill("#inputUsername", cloudron_email) - page.fill("#inputPassword", password) + page.click("#inputUsername") + page.keyboard.type(cloudron_email) + page.click("#inputPassword") + page.keyboard.type(password) - # Submit: Cloudron uses different button types on panel vs OIDC pages - page.evaluate("""() => { - const selectors = [ - "button.btn-primary", - 'button[type="submit"]', - 'input[type="submit"]', - "#loginSubmitButton", - ]; - for (const sel of selectors) { - const el = document.querySelector(sel); - if (el) { el.click(); return; } - } - }""") + # Submit: Cloudron Pankow UI uses
instead of