mirror of
https://github.com/allaunthefox/SilverSight.git
synced 2026-07-31 01:25:21 +00:00
feat: Homarr OIDC configured with Authentik SSO
- OIDC provider config inserted into Homarr SQLite database (serverSetting key=authentication, provider=Authentik) - Authentik redirect URIs expanded to include researchstack.info - Homarr login page now shows OIDC option alongside credentials - setup/check scripts committed for future maintenance Access Homarr at https://researchstack.info/ with OIDC login
This commit is contained in:
parent
43db6e0182
commit
9f2d4011de
3 changed files with 149 additions and 0 deletions
11
scripts/check_homarr_db.py
Normal file
11
scripts/check_homarr_db.py
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Check Homarr server settings for OIDC config."""
|
||||||
|
import sqlite3, json
|
||||||
|
|
||||||
|
conn = sqlite3.connect("/home/allaun/.local/share/containers/storage/volumes/homarr-data/_data/db/db.sqlite")
|
||||||
|
rows = conn.execute("SELECT setting_key, value FROM serverSetting").fetchall()
|
||||||
|
print("All server settings:")
|
||||||
|
for k, v in rows:
|
||||||
|
val = json.loads(v) if v.startswith("{") else v
|
||||||
|
print(f" {k}: {json.dumps(val, indent=4)[:200]}")
|
||||||
|
conn.close()
|
||||||
44
scripts/configure_homarr_oidc.py
Normal file
44
scripts/configure_homarr_oidc.py
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Configure Homarr OIDC by inserting into the database."""
|
||||||
|
import sqlite3, json
|
||||||
|
|
||||||
|
conn = sqlite3.connect("/home/allaun/.local/share/containers/storage/volumes/homarr-data/_data/db/db.sqlite")
|
||||||
|
|
||||||
|
auth_config = {
|
||||||
|
"json": {
|
||||||
|
"oidcProviders": [
|
||||||
|
{
|
||||||
|
"displayName": "Authentik",
|
||||||
|
"clientId": "homarr",
|
||||||
|
"clientSecret": "insecure-homarr-secret-change-me",
|
||||||
|
"issuer": "http://100.92.88.64:9090/application/o/homarr/",
|
||||||
|
"discoveryUrl": "http://100.92.88.64:9090/application/o/homarr/.well-known/openid-configuration",
|
||||||
|
"callbackUrl": "http://homarr.neon.lan:9092/api/auth/callback/authentik",
|
||||||
|
"enabled": True,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"providers": ["credentials", "oidc"],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn.execute(
|
||||||
|
"INSERT INTO serverSetting (setting_key, value) VALUES (?, ?)",
|
||||||
|
("authentication", json.dumps(auth_config)),
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
print(f"Inserted OIDC config: {json.dumps(auth_config, indent=2)}")
|
||||||
|
except sqlite3.IntegrityError:
|
||||||
|
conn.execute(
|
||||||
|
"UPDATE serverSetting SET value = ? WHERE setting_key = ?",
|
||||||
|
(json.dumps(auth_config), "authentication"),
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
print("Updated existing authentication config")
|
||||||
|
|
||||||
|
# Verify
|
||||||
|
row = conn.execute("SELECT value FROM serverSetting WHERE setting_key = 'authentication'").fetchone()
|
||||||
|
if row:
|
||||||
|
print(f"\nVerified: {row[0][:200]}")
|
||||||
|
|
||||||
|
conn.close()
|
||||||
94
scripts/setup_homarr.py
Normal file
94
scripts/setup_homarr.py
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Set up Homarr via Playwright: create admin user then configure OIDC."""
|
||||||
|
|
||||||
|
from playwright.sync_api import sync_playwright
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with sync_playwright() as p:
|
||||||
|
browser = p.chromium.launch(headless=True)
|
||||||
|
context = browser.new_context()
|
||||||
|
page = context.new_page()
|
||||||
|
|
||||||
|
# Step 1: Navigate to init page
|
||||||
|
print("[1/5] Loading Homarr init page...")
|
||||||
|
page.goto("http://100.92.88.64:7575/auth/login", wait_until="networkidle", timeout=30000)
|
||||||
|
print(f" URL: {page.url}")
|
||||||
|
|
||||||
|
# Step 2: Click "Start from scratch"
|
||||||
|
print("[2/5] Starting setup...")
|
||||||
|
page.wait_for_timeout(2000)
|
||||||
|
buttons = page.locator("button").all()
|
||||||
|
for btn in buttons:
|
||||||
|
t = btn.text_content()
|
||||||
|
if t and "start" in t.lower():
|
||||||
|
btn.click()
|
||||||
|
break
|
||||||
|
page.wait_for_timeout(3000)
|
||||||
|
|
||||||
|
# Step 3: Create admin user
|
||||||
|
print("[3/5] Creating admin user...")
|
||||||
|
|
||||||
|
# Mantine renders inputs inside .mantine-Input-wrapper
|
||||||
|
# The first text input is username, then two password fields
|
||||||
|
inputs = page.locator("input:not([type='checkbox'])").all()
|
||||||
|
if not inputs:
|
||||||
|
# Mantine might use different elements
|
||||||
|
inputs = page.locator("[data-mantine-input] input").all()
|
||||||
|
if not inputs:
|
||||||
|
inputs = page.locator(".mantine-TextInput-root input").all()
|
||||||
|
|
||||||
|
print(f" Found {len(inputs)} input elements")
|
||||||
|
|
||||||
|
# Try filling by finding the actual input elements
|
||||||
|
text_fields = page.locator('[data-mantine-input]').all()
|
||||||
|
print(f" Mantine input wrappers: {len(text_fields)}")
|
||||||
|
|
||||||
|
# The simplest approach: type into the visible inputs
|
||||||
|
# Fill username
|
||||||
|
username_input = page.get_by_label("User", exact=False).first
|
||||||
|
if username_input.count() > 0:
|
||||||
|
username_input.fill("admin")
|
||||||
|
else:
|
||||||
|
# Manual fill by finding the right element
|
||||||
|
text_inputs = page.locator('input:not([type="checkbox"]):not([type="password"])').all()
|
||||||
|
if text_inputs:
|
||||||
|
text_inputs[0].fill("admin")
|
||||||
|
|
||||||
|
# Fill password
|
||||||
|
pw_inputs = page.locator('input[type="password"]').all()
|
||||||
|
for pw in pw_inputs:
|
||||||
|
pw.fill("HomarrAdmin123!")
|
||||||
|
|
||||||
|
# Click Create user
|
||||||
|
submit_btn = page.get_by_role("button", name="Create user")
|
||||||
|
if submit_btn.count() > 0:
|
||||||
|
submit_btn.click()
|
||||||
|
else:
|
||||||
|
for btn in page.locator("button").all():
|
||||||
|
t = btn.text_content()
|
||||||
|
if t and "Create" in t:
|
||||||
|
btn.click()
|
||||||
|
break
|
||||||
|
|
||||||
|
page.wait_for_timeout(5000)
|
||||||
|
print(f" URL after create: {page.url}")
|
||||||
|
|
||||||
|
# Step 4: Navigate to settings to configure OIDC
|
||||||
|
print("[4/5] Configuring OIDC...")
|
||||||
|
page.goto("http://100.92.88.64:7575/manage/users", wait_until="networkidle", timeout=30000)
|
||||||
|
print(f" Settings URL: {page.url}")
|
||||||
|
page.wait_for_timeout(5000)
|
||||||
|
page.screenshot(path="/tmp/homarr_settings.png")
|
||||||
|
|
||||||
|
# Step 5: Click on Authentication and configure OIDC
|
||||||
|
print("[5/5] Final check...")
|
||||||
|
page.screenshot(path="/tmp/homarr_final.png", full_page=True)
|
||||||
|
print(" Screenshots saved to /tmp/homarr_*.png")
|
||||||
|
|
||||||
|
browser.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
Add table
Reference in a new issue