Add Autodesk callback port setting

Persist the OAuth callback port in connector settings, expose it in the settings dialog, and use it when constructing the localhost callback URL.

Generated with the assistance of an AI coding tool.
This commit is contained in:
Dion Moult
2026-05-20 12:22:42 +10:00
parent dc82171013
commit 49f6f64e5c
4 changed files with 39 additions and 4 deletions
+5 -2
View File
@@ -28,7 +28,7 @@ bonsaiviewer-autodesk
The connector launches without any configuration; on first run, invoke
`open_settings` (or, equivalently, set the `APS_CLIENT_ID` env var) to
configure the Autodesk client id.
configure the Autodesk client id and OAuth callback port.
Then send newline-delimited JSON-RPC 2.0 requests on `stdin`. Examples:
@@ -51,6 +51,9 @@ The connector reads the Autodesk client id from two places, in order:
overrides).
2. `<config dir>/settings.json` (persisted via the settings dialog).
The OAuth callback host is always `localhost`. The callback port defaults to
`8080` and can be changed in the settings dialog.
The config directory is platform-specific:
- Linux: `~/.config/bonsaiviewer-autodesk/`
@@ -85,7 +88,7 @@ What is implemented:
- Hub / project / folder browsing (Qt UI)
- `pull_ifcfed_interactive`, `pull_ifcfed`, `pull_models`, `pull_models_interactive`
- `push_ifcfed_interactive`, `push_ifcfed`, `push_model_interactive`, `push_model`
- `open_settings` — edit the client id, sign out
- `open_settings` — edit the client id and callback port, sign out
- Connector-managed cache with sole-child invariant
- Adjacent `.ifcfed.manifest` written/read alongside `.ifcfed` files
@@ -35,7 +35,6 @@ def _upload_callback(report: Report) -> ApsProgress:
CONNECTOR_ID = "autodesk"
KEYRING_SERVICE = "bonsaiviewer-autodesk"
DEFAULT_CALLBACK_URL = "http://localhost:8080/"
DEFAULT_SCOPE = "data:read data:write data:create"
@@ -53,9 +52,10 @@ class AutodeskConnector:
self.aps = None
return
token_store = KeyringTokenStore(service_name=KEYRING_SERVICE, username=client_id)
callback_url = f"http://localhost:{settings.stored_callback_port()}/"
self.auth = AuthSessionService(
client_id=client_id,
callback_url=DEFAULT_CALLBACK_URL,
callback_url=callback_url,
scope=DEFAULT_SCOPE,
token_store=token_store,
)
@@ -7,6 +7,9 @@ from pathlib import Path
from typing import Any
DEFAULT_CALLBACK_PORT = 8080
def config_root() -> Path:
system = platform.system()
if system == "Windows":
@@ -59,3 +62,20 @@ def save_client_id(client_id: str) -> None:
data = _read()
data["client_id"] = client_id.strip()
_write(data)
def stored_callback_port() -> int:
value = _read().get("callback_port", DEFAULT_CALLBACK_PORT)
try:
port = int(value)
except (TypeError, ValueError):
return DEFAULT_CALLBACK_PORT
return port if 1 <= port <= 65535 else DEFAULT_CALLBACK_PORT
def save_callback_port(port: int) -> None:
if not 1 <= port <= 65535:
raise ValueError("Callback port must be between 1 and 65535.")
data = _read()
data["callback_port"] = port
_write(data)
@@ -550,6 +550,7 @@ class SettingsDialog(_BaseDialog):
env_override = settings.env_client_id()
stored = settings.stored_client_id()
effective = env_override or stored
callback_port = settings.stored_callback_port()
body = ctk.CTkFrame(self, fg_color="transparent")
body.pack(fill="both", expand=True, padx=24, pady=24)
@@ -583,6 +584,11 @@ class SettingsDialog(_BaseDialog):
text_color=("#b45309", "#f59e0b"),
).pack(fill="x", pady=(0, 8))
ctk.CTkLabel(body, text="OAuth callback port", anchor="w").pack(fill="x")
self.callback_port_entry = ctk.CTkEntry(body, placeholder_text=str(settings.DEFAULT_CALLBACK_PORT))
self.callback_port_entry.pack(fill="x", pady=(6, 8))
self.callback_port_entry.insert(0, str(callback_port))
self.status_label = ctk.CTkLabel(
body,
text=f"Signed in as {effective}" if effective else "No client id configured.",
@@ -618,6 +624,12 @@ class SettingsDialog(_BaseDialog):
def _save(self) -> None:
new_id = self.client_id_entry.get().strip()
try:
callback_port = int(self.callback_port_entry.get().strip())
settings.save_callback_port(callback_port)
except ValueError:
show_error(title="Invalid Callback Port", message="Callback port must be a number between 1 and 65535.")
return
settings.save_client_id(new_id)
try:
self.connector.reload_credentials()